У меня есть программа, которая загружает .so файл из linux, который работает без проблем.Сейчас я пытаюсь сделать программу кроссплатформенной.После непродолжительных усилий мне удалось скомпилировать dll-файл для поддержки Windows, но когда я попытался загрузить из ctypes, я получаю эту ошибку:
"WindowsError: исключение: нарушение прав доступа, запись 0x0000000000000000"
Кажется, он даже не может правильно передать аргументы моей c-функции.Я думаю, что, возможно, допустил некоторую ошибку при конвертации моего c-кода для Windows DLL или моего кода python, возможно, потребуется больше работы для правильной загрузки dll и использования его в Windows.Я знаком с Python, но я новичок в обоих типах и C .Я пытался найти то, что мне не хватает, но не мог понять, что делать.: (
Я попробовал еще несколько вещей и нашел, где возникает ошибка, но все еще не знаю, как ее решить. Поэтому моя проблема возникает, когда функция dll пытается вызвать другую функцию dll внутри.обновил мой код, добавив эту часть.
Я проверил, что другой вызов dll ("mylib.dll") внутри моего c-кода работает нормально, вызывая initfunc внутри главной функции (в другом c-коде)с тем же соглашением о вызовах.) Так что мой mylib.dll не имеет проблемы. Я предполагаю, что мне, возможно, придется сделать что-то еще, если я хочу вызвать функцию dll из функции dll?
Ниже приведен мой c-код для linux и Windows и как я их называю на python.
Я отредактировал свой код так, чтобы это был пример Minimal, Complete и Verifiable, как предложил Антти.Я новичок в Stack Overflow и сначала не понимал, что значит делать «Минимальный, завершенный и проверяемый пример». Спасибо за совет и извините за мое невежество. Теперь я могу воспроизвести ту же проблему с моимкод ниже.
//header param_header.h
typedef struct MYSTRUCT MYSTRUCT;
struct MYSTRUCT
{
double param1;
double param2;
};
//mylib.c this was compiled as an .so(gcc mylib.c -fPIC -shared -o mylib.so) and .dll
#include "param_header.h"
#include <stdio.h>
#ifdef __linux__
int update_param(char *pstruct, char *paramname, double param)
#else
__declspec(dllexport) int update_param(char *pstruct, char *paramname, double param)
#endif
{
printf("Print this if function runs");
return 0;
}
//my_c_code.c --> this compiled again an .so & .dll and called by python ctypes
#include "param_header.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __linux__
#include <dlfcn.h>
#else
#include <windows.h>
#endif
#ifdef __linux__
MYSTRUCT *initfunc(flag, number, params, paramnames)
#else
__declspec(dllexport) MYSTRUCT *initfunc(flag, number, params, paramnames)
#endif
int flag;
int number;
double params[100];
char *paramnames[100];
{
int index;
int check;
MYSTRUCT *pstruct=(MYSTRUCT *)malloc(sizeof(MYSTRUCT));
memset(pstruct,0,sizeof(MYSTRUCT));
#ifdef __linux__
void *pHandle;
pHandle=dlopen("./mylib.so",RTLD_LAZY);
int(*update_param)(char*, char*, double) = dlsym(pHandle, "update_param");
#else
HINSTANCE pHandle;
pHandle=LoadLibrary("./mylib.dll");
int(__cdecl *update_param)(char*,char*, double);
FARPROC updateparam = GetProcAddress(pHandle, "update_param");
if (!updateparam)
{
check = GetLastError();
printf("%d\n", check);
}
update_param = (int(__cdecl *)(char*, char*, double))updateparam;
#endif
for (index=0;index < number;index++) {
(*update_param)((char*)pstruct, paramnames[index],params[index]); // <--this line fails only for the windows.
}
return pstruct;
}
А ниже приведен мой код Python для доступа к функции.
//mystruct.py
from ctypes import *
class MYSTRUCT(Structure):
_fields_ = [("param1",c_double),
("param2",c_double)]
//mypython code
from ctypes import *
from mystruct import *
mydll=cdll.LoadLibrary("./my_c_code.so")#"./my_c_code.dll" for windows.
libhandle=mydll._handle
c_initfunc=mydll.initfunc
c_initfunc.restype=POINTER(MYSTRUCT)
c_initfunc.argtypes=[c_int,c_int,c_double*100,c_char_p*100]
import numpy as np
param_dict={"a":1,"b":2}
params=(c_double * 100)(*np.float_(param_dict.values()))
paramnames=(c_char_p * 100)(*param_dict.keys())
flag=c_int(1)
number=c_int(len(param_dict.values()))
out=c_initfunc(flag, number, params, paramnames) <-- Error here.
Я не уверен, достаточно ли этой информации для отладки ... но с комбинациейвыше код Python и Linux c-код скомпилированный файл ".so".У меня нет никаких проблем .. но я получаю ошибку для дела DLL.Любая идея будет оценена.