84 lines
2.7 KiB
C
84 lines
2.7 KiB
C
|
/*
|
||
|
This module uses the Python CObject or Capsule interface to import pointers to
|
||
|
functions and variables defined in the _quisk Python extension module. These functions and
|
||
|
variables can then be used in another extension module. This is an alternative to linking
|
||
|
the other extension module to _quisk with the C linker. This interface is used by the SDR-IQ
|
||
|
extension module, and you can use that as a model.
|
||
|
|
||
|
This feature exists because of Maitland Bottoms, AA4HS, who requested the feature and provided patches.
|
||
|
|
||
|
To use this interface in your own extension module, first modify your setup.py or makefile so that
|
||
|
you are not linking in symbols from the _quisk module. Add import_quisk_api.c to your source files.
|
||
|
|
||
|
Then add this define before including quisk.h:
|
||
|
#define IMPORT_QUISK_API
|
||
|
#include "quisk.h"
|
||
|
|
||
|
Add this code after Py_InitModule() in your module init function (PyMODINIT_FUNC):
|
||
|
// Import pointers to functions and variables from module _quisk
|
||
|
if (import_quisk_api()) {
|
||
|
printf("Failure to import pointers from _quisk\n");
|
||
|
return; //Error
|
||
|
}
|
||
|
|
||
|
Use this new function to set your Start/Stop/Read functions (if used):
|
||
|
quisk_sample_source(&quisk_start_sdriq, &quisk_stop_sdriq, &quisk_read_sdriq);
|
||
|
|
||
|
Change references to quisk_sound_state to use the pointer pt_quisk_sound_state everywhere. For
|
||
|
example, replace this:
|
||
|
quisk_sound_state.read_error++;
|
||
|
with this:
|
||
|
pt_quisk_sound_state->read_error++;
|
||
|
*/
|
||
|
|
||
|
#include <Python.h>
|
||
|
|
||
|
void ** Quisk_API; // array of pointers to functions and variables from module _quisk
|
||
|
struct sound_conf * pt_quisk_sound_state; // pointer to quisk_sound_state
|
||
|
|
||
|
#if ( (PY_VERSION_HEX < 0x02070000) || ((PY_VERSION_HEX >= 0x03000000) && (PY_VERSION_HEX < 0x03010000)) )
|
||
|
// Old Python interface using CObject
|
||
|
int import_quisk_api(void)
|
||
|
{
|
||
|
PyObject *c_api_object;
|
||
|
PyObject *module;
|
||
|
|
||
|
module = PyImport_ImportModule("_quisk");
|
||
|
if (module == NULL) {
|
||
|
printf("Failure 1 to import Quisk_API\n");
|
||
|
return -1;
|
||
|
}
|
||
|
c_api_object = PyObject_GetAttrString(module, "QUISK_C_API");
|
||
|
if (c_api_object == NULL) {
|
||
|
Py_DECREF(module);
|
||
|
printf("Failure 2 to import Quisk_API\n");
|
||
|
return -1;
|
||
|
}
|
||
|
if (PyCObject_Check(c_api_object)) {
|
||
|
Quisk_API = (void **)PyCObject_AsVoidPtr(c_api_object);
|
||
|
}
|
||
|
else {
|
||
|
printf("Failure 3 to import Quisk_API\n");
|
||
|
Py_DECREF(c_api_object);
|
||
|
Py_DECREF(module);
|
||
|
return -1;
|
||
|
}
|
||
|
Py_DECREF(c_api_object);
|
||
|
Py_DECREF(module);
|
||
|
pt_quisk_sound_state = (struct sound_conf *)Quisk_API[0];
|
||
|
return 0;
|
||
|
}
|
||
|
#else
|
||
|
// New Python interface using Capsule
|
||
|
int import_quisk_api(void)
|
||
|
{
|
||
|
Quisk_API = (void **)PyCapsule_Import("_quisk.QUISK_C_API", 0);
|
||
|
if (Quisk_API == NULL) {
|
||
|
printf("Failure to import Quisk_API\n");
|
||
|
return -1;
|
||
|
}
|
||
|
pt_quisk_sound_state = (struct sound_conf *)Quisk_API[0];
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|