2015-03-11 6 views
2

Я пытаюсь построить (очень простое) расширение Python из кода C и запутался в компиляции.Установка модуля Python завершается сбоем, поскольку в команде gcc отсутствует флаг ... что команда gcc имеет

(Для записи: мои навыки C очень устарелый и мой код, вероятно, ужасно.)

По указанию in the docs и another site I found, я создал файл C, который предоставляет функциональные возможности мне нужно встроенный в модуль Python:

#include "strcrypto.h" 
#include <stdlib.h> 

#define CRYPTO_POOLNUMBER 15 

int main() { 
    return 0; 
} 

char* encryptString(char* string) { 
    COMM* comm; 
    char* encrypted_string = malloc(sizeof(char) * 4096); 
    int res; 

    comm = init_client(CRYPTO_PORT); 

    if (comm == NULL) { 
     return NULL; 
    } 

    res = StrEncrypt(comm, string, encrypted_string, CRYPTO_POOLNUMBER); 

    end_client(comm); 
    if (res != 1) { 
     return NULL; 
    } 
    else { 
     return encrypted_string; 
    } 
} 

char* decrypt(char* string) { 
    COMM* comm; 
    char* decrypted_string = malloc(sizeof(char) * 4096); 
    int res; 

    comm = init_client(CRYPTO_PORT); 

    if (comm == NULL) { 
     return NULL; 
    } 

    res = StrDecrypt(comm, string, decrypted_string); 

    end_client(comm); 
    if (res != 1) { 
     return NULL; 
    } 
    else { 
     return decrypted_string; 
    } 
} 

char* randomToken(char* string) { 
    COMM* comm; 
    char* token = malloc(sizeof(char) * 4096); 
    int res; 

    comm = init_client(CRYPTO_PORT); 

    if (comm == NULL) { 
     return NULL; 
    } 

    res = getPBToken(comm, string, token); 

    end_client(comm); 
    if (res != 1) { 
     return NULL; 
    } 
    else { 
     return token; 
    } 
} 

char* fixedToken(char* string) { 
    COMM* comm; 
    char* token = malloc(sizeof(char) * 4096); 
    int res; 

    comm = init_client(CRYPTO_PORT); 

    if (comm == NULL) { 
     return NULL; 
    } 

    res = getFixedToken(comm, string, token); 

    end_client(comm); 
    if (res != 1) { 
     return NULL; 
    } 
    else { 
     return token; 
    } 
} 

Я также создал файл C, который оборачивает методы для Python:

#include <Python.h> 

static PyObject* crypto_encrypt(PyObject* self, PyObject* args) { 
    char* original_string; 
    char* encrypted_string; 
    PyObject* return_value; 

    if (!PyArg_ParseTuple(args, "s", &original_string)) { 
     return NULL; // Could not parse string or no string was passed. 
    } 

    encrypted_string = encryptString(original_string); 

    if (encrypted_string == NULL) { 
     return NULL; 
    } 
    else { 
     return_value = PyString_FromString(encrypted_string); 
     free(encrypted_string); 
     return return_value; 
    } 
} 

static PyObject* crypto_decrypt(PyObject* self, PyObject* args) { 
    char* original_string; 
    char* decrypted_string; 
    PyObject* return_value; 

    if (!PyArg_ParseTuple(args, "s", &original_string)) { 
     return NULL; // Could not parse string or no string was passed. 
    } 

    decrypted_string = decryptString(original_string); 

    if (decrypted_string == NULL) { 
     return NULL; 
    } 
    else { 
     return_value = PyString_FromString(decrypted_string); 
     free(decrypted_string); 
     return return_value; 
    } 
} 

static PyObject* crypto_fixedToken(PyObject* self, PyObject* args) { 
    char* original_string; 
    char* token; 
    PyObject* return_value; 

    if (!PyArg_ParseTuple(args, "s", &original_string)) { 
     return NULL; // Could not parse string or no string was passed. 
    } 

    token = fixedToken(original_string); 

    if (token == NULL) { 
     return NULL; 
    } 
    else { 
     return_value = PyString_FromString(token); 
     free(token); 
     return return_value; 
    } 
} 

static PyObject* crypto_randomToken(PyObject* self, PyObject* args) { 
    char* original_string; 
    char* token; 
    PyObject* return_value; 

    if (!PyArg_ParseTuple(args, "s", &original_string)) { 
     return NULL; // Could not parse string or no string was passed. 
    } 

    token = randomToken(original_string); 

    if (token == NULL) { 
     return NULL; 
    } 
    else { 
     return_value = PyString_FromString(token); 
     free(token); 
     return return_value; 
    } 
} 

static PyMethodDef CryptoMethods[] = { 
    { "encrypt", crypto_encrypt, METH_VARARGS, "Encrypt text using a Crypto server." }, 
    { "decrypt", crypto_decrypt, METH_VARARGS, "Decrypt text encrypted using a Crypto server." }, 
    { "getFixedToken", crypto_fixedToken, METH_VARARGS, "Return a fixed PKCS5 token from Crypto." }, 
    { "getRandomToken", crypto_randomToken, METH_VARARGS, "Return a random PKCS5 token from Crypto." }, 
    { NULL, NULL, 0, NULL } 
}; 

PyMODINIT_FUNC initcrypto(void) { 
    (void) Py_InitModule("crypto", CryptoMethods); 
} 

Наконец, я создал setup.py файл, который создает расширение и требует установки() о продлении:

from distutils.core import setup, Extension 

ext = Extension("crypto", 
    ["cryptomodule.c", "crypto.c"], 
    libraries = ["strcrypto",], 
    library_dirs = ["/usr/local/lib",] 
) 

setup(name = "crypto", ext_modules = [ext,]) 

Библиотека «strcrypto» на самом деле «libstrcrypto.a» и была предоставлена ​​мне; это не то, что я написал. К сожалению, это также то, что, как представляется, вызывает ошибку, когда я иду установить файл:

running install 
running build 
running build_ext 
building 'crypto' extension 
x86_64-linux-gnu-gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.7 -c cryptomodule.c -o build/temp.linux-x86_64-2.7/cryptomodule.o 
cryptomodule.c: In function ‘crypto_encrypt’: 
cryptomodule.c:15:5: warning: implicit declaration of function ‘encryptString’ [-Wimplicit-function-declaration] 
    encrypted_string = encryptString(original_string); 
    ^
cryptomodule.c:15:22: warning: assignment makes pointer from integer without a cast [enabled by default] 
    encrypted_string = encryptString(original_string); 
        ^
cryptomodule.c: In function ‘crypto_decrypt’: 
cryptomodule.c:36:5: warning: implicit declaration of function ‘decryptString’ [-Wimplicit-function-declaration] 
    decrypted_string = decryptString(original_string); 
    ^
cryptomodule.c:36:22: warning: assignment makes pointer from integer without a cast [enabled by default] 
    decrypted_string = decryptString(original_string); 
        ^
cryptomodule.c: In function ‘crypto_fixedToken’: 
cryptomodule.c:57:5: warning: implicit declaration of function ‘fixedToken’ [-Wimplicit-function-declaration] 
    token = fixedToken(original_string); 
    ^
cryptomodule.c:57:11: warning: assignment makes pointer from integer without a cast [enabled by default] 
    token = fixedToken(original_string); 
     ^
cryptomodule.c: In function ‘crypto_randomToken’: 
cryptomodule.c:78:5: warning: implicit declaration of function ‘randomToken’ [-Wimplicit-function-declaration] 
    token = randomToken(original_string); 
    ^
cryptomodule.c:78:11: warning: assignment makes pointer from integer without a cast [enabled by default] 
    token = randomToken(original_string); 
     ^
x86_64-linux-gnu-gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.7 -c crypto.c -o build/temp.linux-x86_64-2.7/crypto.o 
crypto.c:6:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes] 
int main() { 
    ^
x86_64-linux-gnu-gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -Wl,-z,relro -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -D_FORTIFY_SOURCE=2 -g -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security build/temp.linux-x86_64-2.7/cryptomodule.o build/temp.linux-x86_64-2.7/crypto.o -L/usr/local/lib -lstrcrypto -o build/lib.linux-x86_64-2.7/crypto.so 
/usr/bin/ld: /usr/local/lib/libstrcrypto.a(strcrypto.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC 
/usr/local/lib/libstrcrypto.a: error adding symbols: Bad value 
collect2: error: ld returned 1 exit status 
error: command 'x86_64-linux-gnu-gcc' failed with exit status 1 

Я не знаю, что означает, что ошибка, потому что, как вы можете видеть, ССАГПЗ вызовы действительно с помощью - ППИЦ.

Может кто-нибудь указать, что я здесь делаю неправильно? Заранее спасибо.

ответ

1

Расширение Python, которое вы строите, - это общая библиотека. Код в общей библиотеке

должен быть составлен как position independent. Это делается путем компиляции с -fPIC.

Ваша проблема заключается в том, что ваш libstrcrypto.a не скомпилирован с -fPIC и поэтому не может использоваться в общей библиотеке. У вас есть несколько вариантов:

  1. Спросите версии libstrcrypto.a, который компилируется с -fPIC.
  2. Запросить общую библиотечную версию libstrcrypto.a.
  3. Связать свое расширение статически, чтобы создать новый исполняемый файл Python, содержащий встроенное расширение.
  4. Разделите расширение в исполняемый файл, который связывается с библиотекой и расширением python, которое каким-то образом связывается с исполняемым файлом.
+0

Спасибо за ответ. Мой коллега должен вернуться к поставщику и спросить о версии strcrypto, которая скомпилирована с -fPIC. В случае, если он не в состоянии сделать это, каковы мои варианты получения библиотеки strcrypto для работы на Python? – TrevorNT

+0

Компания Nevermind, поставщик поставлял обновленный модуль. В очередной раз благодарим за помощь! – TrevorNT

 Смежные вопросы

  • Нет связанных вопросов^_^