在 Python 中使用回调时出错
我正在开发一个应该在 Python 中使用的 dll.我有一个回调函数来发送我的参数(在单独的标头中定义):
I am developing a dll that should be used in Python. I have a callback function to send my parameters (defined in a separate header):
typedef int(*call_nBest)(char **OutList, float* confList, int nB);
所以,我就是这样使用这个回调的:
So, I'm using this callback in this way:
#define TEXT_BUFFER_MAX_SIZE 50
call_nBest nBestList;
void Xfunction(const char* aLineThatWillBeConvertedInAList){
char **results;
float *confidences;
confidences=new float[nBest];
results=new char*[nBest];
for(int i=0; i<nBest; i++) results[i]=new char[TEXT_BUFFER_MAX_SIZE];
MakeLine2List(aLineThatWillBeConvertedInAList,results,confidences);
/*At this function I am having the error :(*/
nBestList(results,confidences,nBest); // Passing the values to my callback
for(int i=0; i<nBest; i++) delete [] results[i];
delete [] confidences;
delete [] results;
}
我是这样导出的:
__declspec(dllexport) int ResultCallback(call_nBest theList){
nBestList = theList;
return(0);
}
我首先以这种方式在另一个 C++ 应用程序中测试了我的回调:
I tested my callback first in another C++ application in this way:
int MyCallback(char **OutLi, float* confLi, int nB){
printf("
The nB results: %d
",nB);
for(int n=0; n<nB; n++){
std::cout << *(confLi+n) << " " << OutLi[n] << "
";
}
return(0);
}
在main()
中我是这样给回调的:
In main()
I give the callback in this way:
ResultCallback(MyCallback);
而且效果很好.但我不知道如何使它适应 Python.我试过这个:
and it works pretty well. But I don't have any idea how to adapt this to Python. I have tried this:
注意:我改变了最后一种方式,因为我解决了一些错误,但我仍然收到错误.这是我加载 myDLL
Note: I have changed the last way, because I resolved some mistakes, but I'm still getting an error. This is the current way of how I am loading myDLL
from ctypes import *
def callbackU(OutList,ConList,nB):
for i in range(nB):
print(OutList[i][0:50]) #I don't know how to print the values
return 0
myDLL = cdll.LoadLibrary("MyLibrary.dll")
calling = CFUNCTYPE(c_int,POINTER(POINTER(c_char)),POINTER(c_float),c_int)
theCall= calling(callbackU)
myDLL.ResultCallback(theCall)
myDLL.StartProcess(); #In this process the given callback will be invoqued
错误
现在我有这个错误:
ERROR
And now I have this error:
未处理的异常:System.AccessViolationException:试图读或写受保护的内存.这通常表明其他内存已损坏.在 Xfunction(SByte*aLineThatWillBeConvertedInAList)
Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. at Xfunction(SByte* aLineThatWillBeConvertedInAList)
问题事件名称:APPCRASH
应用程序名称:python.exe
应用程序版本:0.0.0.0
申请时间戳:54f9ed12
故障模块名称:MSVCR100.dll
故障模块版本:10.0.40219.325
故障模块时间戳:10.0.40219.325
异常代码:c0000005
异常偏移:00001ed7
操作系统版本:6.3.9600.2.0.0.256.4
区域设置 ID:1033
附加信息 1:5861
附加信息2:5861822e1919d7c014bbb064c64908b2
附加信息 3:a10f
附加信息4:a10ff7d2bb2516fdc753f9c34fc3b069
Problem Event Name: APPCRASH
Application Name: python.exe
Application Version: 0.0.0.0
Application Timestamp: 54f9ed12
Fault Module Name: MSVCR100.dll
Fault Module Version: 10.0.40219.325
Fault Module Timestamp: 10.0.40219.325
Exception Code: c0000005
Exception Offset: 00001ed7
OS Version: 6.3.9600.2.0.0.256.4
Locale ID: 1033
Additional Information 1: 5861
Additional Information 2: 5861822e1919d7c014bbb064c64908b2
Additional Information 3: a10f
Additional Information 4: a10ff7d2bb2516fdc753f9c34fc3b069
我已经做过并且几乎是我想要的事情:
首先我为这个更改了回调 Python 函数:
Things that I've done and are almost what I want:
First I changed the callback Python function for this one:
def callbackU(OutList,ConList,nB):
for i in range(nB):
print(i)
return 0
一切正常,我可以在控制台中看到这一点(在这种情况下,nB
是 10
):
All works with no error and I can see this in the Console (in this case nB
was 10
):
0
1
...
9
其次,我把功能改成了这个:
Second, I changed the function as this one:
def callbackU(OutList,ConList,nB):
for i in range(nB):
print (cast(OutList,c_char_p))
return 0
而且,哦,令人惊讶的是,这只会打印列表的第一个单词(nB 次)
and, oh surprise this prints only the first word of the list (nB times)
推荐答案
你想要这样的东西吗?
def callbackU(OutList, ConList, nB):
for i in range(nB):
print("{} {}".format(ConList[i], cast(OutList[i], c_char_p)))
return 0
据我了解,您只是想将 Python callbackU
函数的输出与 C++ MyCallback
函数相匹配.
From what I understand you're just trying to match the output of your Python callbackU
function with your C++ MyCallback
function.
Python 有多种字符串格式化功能,一开始可能会让人困惑,但它向 printf 致敬
字符串格式化.
Python has a variety of string formatting functionality that can be confusing at first, but pays homage to printf
string formatting.
由于 OutList
的类型为 LP_LP_c_char
(指向 c_char
的指针的指针,vs "NULL 终止的 char *
"c_char_p
),我们最好把它变成一个原生的 Python 数据类型,像这样:
Since OutList
has type LP_LP_c_char
(pointer to pointer of c_char
, vs "NULL terminated char *
" c_char_p
), we'd best turn it into a native Python data type like so:
def callbackU(OutList, ConList, nB):
for i in range(nB):
out_list_item = cast(OutList[i], c_char_p).value
print("{} {}".format(ConList[i], out_list_item))
return 0
相关文章