在Python中使用回调时出错 [英] Error using callback in Python

查看:302
本文介绍了在Python中使用回调时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个应该在Python中使用的dll。我有一个回调函数发送我的参数(在一个单独的标题中定义):



typedef int(* call_nBest)因此,我以这种方式使用这个回调函数:



  #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
MakeLine2List(aLineThatWillBeConvertedInAList,results,confidences);

/ *在这个函数我有错误:(* /
nBestList(results,confidences,nBest); //将值传递给我的回调

for(int i = 0; i delete [] confidences;
delete [] results;

}

我以这种方式导出:

  __ declspec(dllexport)int ResultCallback(call_nBest theList){
nBestList = theList;
return(0);
}

我以这种方式在另一个C ++应用程序中测试了我的回调:

  int MyCallback(char ** OutLi,float * confLi,int nB){
printf(\\\
nB results:%d \\\
,nB) ;
for(int n = 0; n std :: cout <*(confLi + n)<\t< OutLi [n]<<; \ n;
}
return(0);
}

main()我以这种方式给回调:

  ResultCallback(MyCallback); 

但我不知道如何适应这个Python。我尝试过:



注意:我改变了最后一种方式,因为我解决了一些错误, 。这是目前的方式,我如何加载 myDLL

 从ctypes import bb 
def callbackU(outList,ConList,nB):
for i in range(nB):
print(OutList [i] [0:50])#如何打印值
return 0

myDLL = cdll.LoadLibrary(MyLibrary.dll)

calling = CFUNCTYPE(c_int,POINTER )),POINTER(c_float),c_int)
theCall = calling(callbackU)
myDLL.ResultCallback(theCall)

myDLL.StartProcess #在此过程中,给定的回调将被调用



ERROR



现在我有这个错误:


未处理的异常:System.AccessViolationException:尝试
读或写保护内存。这通常表明其他
内存已损坏。

问题签名:

问题事件名称:APPCRASH < br>
应用程序名称: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 :5861822e1919d7c014bb064c64908b2

其他信息3:a10f

其他信息4:a10ff7d2bb2516fdc753f9c34fc3b069




我已经做了,几乎是我想要的:



首先我改变了这个回调Python函数:

  def callbackU(OutList,ConList,nB):
for i in range(nB):
print(i)
return 0

所有工作没有错误,我可以在控制台中看到这个(在这种情况下 nB 10 ):

  0 
1
...
9

函数如下:

  def callbackU(OutList,ConList,nB):
for i in range ):
print(cast(outList,c_char_p))
return 0

(nB次)

解决方案

你想要这样的东西吗? / p>

  def callbackU(OutList,ConList,nB):
for i in range(nB):
print ({} \t {}。格式(ConList [i],cast(outList [i],c_char_p)))
return 0

从我的理解你只是试图匹配Python callbackU 函数的输出与您的C ++ MyCallback 函数。



Python有各种各样的字符串格式化功能,可以先混淆,但支持 printf 字符串格式化。



由于 OutList 有类型 LP_LP_c_char (指向 c_char ,vsNULL terminated char * c_char_p ),我们最好将其转换为本地Python数据类型如下:

  def callbackU(OutList,ConList,nB):
for i in range ):
out_list_item = cast(outList [i],c_char_p).value
print({} \t {}。format(ConList [i],out_list_item))
return 0


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;

}

And I'm exporting it in this way:

__declspec(dllexport) int ResultCallback(call_nBest theList){
    nBestList = theList;
    return(0);
}

I tested my callback first in another C++ application in this way:

int MyCallback(char **OutLi, float* confLi, int nB){
    printf("\n The nB results: %d \n",nB);
    for(int n=0; n<nB; n++){
        std::cout << *(confLi+n) << "\t" << OutLi[n] << "\n";
    }
    return(0);
}

In main() I give the callback in this way:

ResultCallback(MyCallback);

and it works pretty well. But I don't have any idea how to adapt this to Python. I have tried this:

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:

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)

Problem signature:

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

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

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

and, oh surprise this prints only the first word of the list (nB times)

解决方案

Do you want something like this?

def callbackU(OutList, ConList, nB):
    for i in range(nB):
        print("{}\t{}".format(ConList[i], cast(OutList[i], c_char_p)))
    return 0

From what I understand you're just trying to match the output of your Python callbackU function with your C++ MyCallback function.

Python has a variety of string formatting functionality that can be confusing at first, but pays homage to printf string formatting.

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("{}\t{}".format(ConList[i], out_list_item))
    return 0

这篇关于在Python中使用回调时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆