我在D7中创建了一个示例项目,展示了这个奇怪的问题。是这里: http://speedy.sh/n9Etr/OpenCV-BugTest.zip
我有一个看起来像这样的程序:
function Rec (image: PIplImage): String;
begin
DLL_CALL;
end;
当我调用Rec时,我在DLL_CALL上获得AV,但是...... 如果我将第二个参数添加到函数中:
function Rec (image: PIplImage; Something: String): String;
begin
DLL_CALL;
end;
然后DLL_CALL成功。
变量:'Something'是无关紧要的,不会被带到任何地方......
真的,我不知道发生了什么......
我使用openCV库的cvSaveImage。
function cvSaveImage(const filename: PAnsiChar; const image: pointer): integer;
cdecl; external CV_HIGH_GUI_DLL;
我的所有方法都是用cdecl param的调用约定导出的。
完整的程序是:
function TCVR.Rec(image: PIplImage): String;
const
THRESH = 50;
var
imgDisorted: PIplImage;
Storage: PCvMemStorage;
Squares: PCvSeq;
begin
imgDisorted := nil;
result := '';
Storage := cvCreateMemStorage(0);
cvSetImageROI(image, cvRect(0, 0, image^.width and -2, image^.height and -2));
PyrDownUp(image);
cvSetImageROI(image, cvRect(0, 0, image^.width and -2, image^.height and -2));
imgDisorted := cvCreateImage(cvSize(image^.width and -2, image^.height and -2), 8, 1);
cvSaveImage('c:\test.jpg', image); <--- AV here only when I have 1 parameter in my Rec.
end;
答案 0 :(得分:1)
您正在使用带有2.4.1 DLL版本的1.0函数定义。功能定义发生了变化,因此您将近三年过时。特别是cvSaveImage
expects three parameters,而不仅仅是两个。摘自the 2.0 release:
CVAPI(int) cvSaveImage( const char* filename, const CvArr* image,
const int* params CV_DEFAULT(0) );
更新您的DLL导入单元以匹配您正在使用的DLL(或切换到较旧版本的库)。我会将这个函数翻译成Delphi:
function cvSaveImage(filename: PAnsiChar; image: PCvArr; params: PInteger = nil); cdecl;
以下是您遇到特定故障的原因:
DLL不知道您只传递了两个参数,因此它从它认为是第三个参数的内容中读取并将其解释为指向整数数组的指针。不管是什么,可能根本就没有指针,所以你得到了一个访问冲突。
在Rec
函数中添加其他参数会导致其有四个参数(Self
,image
,Something
和Result
),这会强制一个参数参数堆栈。由于堆栈稍大,DLL最终会从不同的位置读取。该位置可能包含空指针,因此DLL不会尝试读取任何数组元素,因此代码按预期工作。
答案 1 :(得分:1)
检查dll的导入声明。可能这个dll的界面已经改变,但是你的代码没有反映出来。