呼叫c++;来自python的函数
我遇到一个问题,这个dll java或php可以调用成功,但当我使用python调用get access violation error时 < P> >我想知道C++ Car是CcHyLp p的错误,我如何使用Python cType地图C++ Car */P> c++dll定义呼叫c++;来自python的函数,python,c++,dll,Python,C++,Dll,我遇到一个问题,这个dll java或php可以调用成功,但当我使用python调用get access violation error时 < P> >我想知道C++ Car是CcHyLp p的错误,我如何使用Python cType地图C++ Car */P> c++dll定义 #define Health_API extern "C" __declspec(dllexport) Health_API unsigned long Initialization(int m_type,char *
#define Health_API extern "C" __declspec(dllexport)
Health_API unsigned long Initialization(int m_type,char * m_ip,int m_port)
Health_API int GetRecordCount(unsigned long m_handle)
python代码
from ctypes import *
lib = cdll.LoadLibrary(r"./Health.dll")
inita = lib.Initialization
inita.argtype = (c_int, c_char_p, c_int)
inita.restype = c_ulong
getcount = lib.GetRecordCount
getcount.argtype = c_ulong
getcount.retype = c_int
# here call
handle = inita(5, '127.0.0.1'.encode(), 4000)
print(handle)
result = getcount(handle)
错误信息:
2675930080
Traceback (most recent call last):
File "C:/Users/JayTam/PycharmProjects/DecoratorDemo/demo.py", line 14, in <module>
print(getcount(handle))
OSError: exception: access violation reading 0x000000009F7F73E0
我是win10 x64,我的python环境是annaconda,我更改了与她相同的环境,使用了相同的代码,仍然返回相同的错误
python vs java
虽然我知道这是环境造成的,但我真的想知道到底是什么造成的
python
每次跑步手柄都是不规则号码,我同学的电脑都有规则号码
例如:2885846721995212481777824736,-607161376(我不设置重新键入)
JAVA
也可以得到不带负数的正则数
例如:946288612894541932009458325520945168332
所以我认为应该是这个代码引起的错误,但在其他pc上没有问题,这是惊人的
handle = lib.Initialization(5, '127.0.0.1'.encode(), 4000)
C++ DLL:
有可能有C++源代码,但我可以猜一些< /P> 我认为这没有关系,但是:
缺少一个getcount.retype
,它应该是s
李>restype
- 我总是将
定义为数组而不是元组,如果只有一个参数,我仍然使用一个元素的数组李>argtype
char*
是以空结尾的字符串,那么确实需要使用c\u char\u p
。在这种情况下,强烈建议在m_ip
参数中添加const
如果char*
是指向原始缓冲区(由调用函数填充或不填充)的指针,而不是这里的情况,则需要使用pointer(c\u char)
而不是c\u char\p
基于错误消息,您的<代码>句柄是一个指针,您应该在C++代码中使用该类型:<代码> Value*/Cuff>。在python中,应该使用
c\u void\u p
是64位代码吗?使用什么工具链/编译器来构建DLL?此工具链中无符号长的大小是多少
编辑:以下是问题的原因:
handle
是DLL中的指针,并且肯定是使用编译器构建的,其中long
是64位,但对于Windows上的python 64位long
是32位,无法存储指针。您真的应该使用void*
首先,您可以尝试在python中使用c\u void\p
作为句柄,而无需修改源代码,它可能会根据所使用的编译器而工作。但是,由于<代码>长< /Cord>类型的大小没有任何标准定义,并且可能不能存储指针,所以您确实应该在C++代码<代码>空白>代码>或<代码> uTutpTrtt< /COD> 中使用。
Edit2:如果您使用的是visual studio,而不是GCC,则long的大小只有32位()
所以您必须修复DLL的代码谢谢,您认为win7和win10的区别是什么?我想不出更多的区别了不,问题不在那里。首先,C++代码是错误的,并且必须被固定,如已经解释的:指针不应该放在无符号长整数中,这取决于编译器和平台,它可能不适合于整数。请解释DLL是如何构建的,使用哪个工具链/编译器以及哪个版本。DLL使用vs 2010 build,x64,release,我明天将修复DLL的代码,现在是1:40,我要睡觉了。你应该再次阅读我的消息,我不知道你在使用visual studio。问题也在你的DLL源代码中,因为VisualStudio一个长的不能在64位BuffDy上存储指针,我会告诉C++代码Wrter,我不理解C++ java返回64位值(注意返回数有多大)。在python中,如果不指定重新类型,则默认值为
int
,这是一个有符号整数,因此会看到负数。在python中,您必须使用c\u void\u p
,正如我已经解释过的,您还应该修复DLLIn python ctypesu\u int64
类型的代码,据我所知,该类型不存在。正如我已经解释过的,你应该使用c\u void\u p
即使c函数原型是一个整数。你的shcoolmate的代码是错误的,她只是幸运的是指针适合32位整数。你知道,我会很快修改它
handle = lib.Initialization(5, '127.0.0.1'.encode(), 4000)
Health_API unsigned long Initialization(int m_type,char* m_ip,int m_port)
{
CHandleNode* node;
switch(m_type)
{
case BASEINFO:
{
CBaseInfo* baseInfo = new CBaseInfo;
baseInfo->InitModule(m_ip,m_port);
node = m_info.AddMCUNode((unsigned long)baseInfo);
node->SetType(m_type);
return (unsigned long)baseInfo;
}
break;
case BASEINFO_ALLERGENS:
{
CBaseInfo_Allergens* baseInfo_Allergens = new CBaseInfo_Allergens;
baseInfo_Allergens->InitModule(m_ip,m_port);
node = m_info.AddMCUNode((unsigned long)baseInfo_Allergens);
node->SetType(m_type);
return (unsigned long)baseInfo_Allergens;
}
break;
. (case too many, ... represent them)
.
.
}
return -1;
}
Health_API int GetRecordList(unsigned long m_handle,char* m_index)
{
CHandleNode* node = m_info.GetMCUNode(m_handle);
if( node == NULL)
{
return -1;
}
switch(node->GetType())
{
case BASEINFO:
{
CBaseInfo* baseInfo = (CBaseInfo*)m_handle;
return baseInfo->GetRecordList(m_index);
}
break;
case BASEINFO_ALLERGENS:
{
CBaseInfo_Allergens* baseInfo_Allergens = (CBaseInfo_Allergens *)m_handle;
return baseInfo_Allergens->GetRecordList(m_index);
}
break;
. (case too many, ... represent them)
.
.
}
return -1;
}