Bir C programına bir python programı yerleştirmeye çalışıyorum. İşletim Sistemim Ubuntu 14.04Python'u C'ye Gömme Bağlamada hata - tanımsız başvuru PyString_AsString
Aynı C kod tabanında (ayrı uygulamalar olarak) python 2.7 ve python 3.4 yorumlayıcılarını yerleştirmeye çalışıyorum. Derleme ve bağlantı python 2.7 gömülü çalışır ancak python için 3.4 çalışır. Linker aşamasında başarısız olur. İşte
import sys
def get_version():
version = '.'.join(str(v) for v in sys.version_info[:3])
print("version: ", version)
return version
kullanıyorum programı derlemek benim C kodu (sadece bir örnek değil gerçek kodu)
simple.c
#include <stdio.h>
#include <Python.h>
int main(int argc, char *argv[])
{
PyObject *pName, *pModule, *pFunc, *pValue;
char module[] = "get_version";
char func[] = "get_version";
char module_path[] = ".";
Py_Initialize();
PyObject *sys_path = PySys_GetObject("path");
PyList_Append(sys_path, PyUnicode_FromString(module_path));
pName = PyUnicode_FromString(module);
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if(pModule != NULL)
{
pFunc = PyObject_GetAttrString(pModule, func);
if (pFunc && PyCallable_Check(pFunc))
{
pValue = PyObject_CallObject(pFunc, NULL);
if (pValue != NULL) {
printf("Python version: %s\n", PyString_AsString(pValue));
Py_DECREF(pValue);
}
else {
Py_DECREF(pFunc);
Py_DECREF(pModule);
PyErr_Print();
fprintf(stderr,"Call failed\n");
return 1;
}
}
}
Py_Finalize();
return 0;
}
get_version.py olduğunu gcc.
gcc `python-config --cflags` simple.c `python-config --ldflags`
bayrakları olarak genişletmek:
piton-config --cflags:-I/usr/include/python2.7 -I/usr/include/x86_64-linux-gnu/python2.7 -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes
piton-config LDFLAGS:-L/usr/lib/python2.7/config-x86_64-linux-gnu -L/usr/lib -lpthread -ldl -lutil -lm -lpython2.7 -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions
Sorun olmadan sorunsuz çalışıyor. Ben python3.4 bayraklarıyla aynı derlemeye çalıştığınızda başarısız:
gcc `python3-config --cflags` simple.c `python3-config --ldflags`
bayrakları olarak genişletmek:
piton-config --cflags:-I/usr/include/python3.4m -I/usr/include/python3.4m -Wno-unused-result -g -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes
piton -config - lflalags:-L/usr/lib/python3.4/config-3.4m-x86_64-linux-gnu -L/usr/lib -lpython3.4m -lpthread -ldl -lutil -lm -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions
Hata mesajı:
simple.c: In function ‘main’:
simple.c:27:17: warning: implicit declaration of function ‘PyString_AsString’ [-Wimplicit-function-declaration]
printf("Python version: %s\n", PyString_AsString(pValue));
^
simple.c:27:17: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
/tmp/ccaoMdTo.o: In function `main':
/home/vagrant/c_python_api/simple.c:27: undefined reference to `PyString_AsString'
collect2: error: ld returned 1 exit status
nesneler belirtilen linkeri sırasını değiştirerek çalıştı. Ama şans yok. Bunun neden böyle olacağı hakkında bir fikrin var mı?
Yardımlarınız için teşekkürler!
Hızlı yanıt için teşekkür ederiz. Sizin tarafınızdan sağlanan çözüm işe yaradı. Python3 dizelerinin varsayılan olarak kodlanmış unicode olduğunu biliyordum, bunun hakkında bir düşünceye sahip olmalıydı. Ancak, çözümünüzde belirtildiği gibi UTF8String PyObject'dir ve yerel karakterlere dönüştürülemez. Burada açıklandığı gibi (http://stackoverflow.com/a/16905726/4104863) PyBytes_AsString() işlevine ek işlev çağrısı yapılmalıdır. Bunu içerecek şekilde cevabı düzenleyeceğim. –
Ah özür dilerim: D Cevap yazıyordu: Sabit –
@JahanBalasubramaniam 'PyUnicode_AsUTF8' olmalıydı; Bu, str'nin kendisi olduğu sürece geçerli olan UTF-8 olarak kodlanmış dizeye paylaşılan bir işaretçi döndürür. –