从delphi XE调用c++ DLL时出现异常
Exception when calling a C++ DLL from Dephi XE
我试图调用一个c++ DLL函数,它是这样定义的:
int read_record (filep *fptr, int key, char *contents, int *status)
这是一个广泛使用的DLL,所以我很确定我遇到的问题是我如何调用函数。
DLL文档中有一个如何调用它的例子
TFILETYPE *fptr; /* file pointer
char contents[80];
int status = 0;
int single = key;
if (read_record(fptr, key, card, &status)) break;
printf("%sn", card);
我认为应该这样做,而且几乎做到了:
type
TCharArray = Array[1..100] of AnsiChar; // Function returns an array less than 100 char
var
read_record : function( var fptr: TFILETYPE;
Key: Integer;
var Contents: TCharArray; // function fills this in
var Status: Integer): Integer cdecl stdcall;
Procedure Test;
var
Contents: TCharArray;
Status: Integer;
Key: Integer;
begin
@read_record:= GetProcAddress(DLLHandle, 'read_record');
for Key := 1 to 10 do
begin
Contents[1] := #0; // shouldn't be necessary
if (read_record( fptr^, Key, Contents, Status) <> 0) OR (Status <> 0) then
ShowMessage('Error')
else
ShowMessage(Contents); // This shows the expected proper string on all 10 calls
...Other calls at this point to other functions in the DLL result in
an Exception writing to x01a.
end;
Delphi XE的多个调用工作良好。但是在那之后,当我在过去一直工作的DLL中调用不同的函数时,我得到一个异常写入x0000001a,我怀疑这意味着我已经破坏了内存或堆栈。
我在调用dll中的其他函数时使用的*fptr指针数据类型,所以我不认为这是问题所在。
这是我第一次尝试调用返回字符串的函数,所以我怀疑我不理解通过引用字符串数组调用的一些东西。
有什么建议,我应该如何调用这个函数不同,以避免什么似乎是垃圾内存?
你这里有几个问题。
首先,Delphi中的函数声明是错误的。首先,它同时声明为cdecl
和stdcall
。它必须是其中之一;两者不能同时发生。
另外,在fptr
变量上有一个额外的解引用级别。
声明表明它是一个指针:
filep *fptr
你在Delphi声明中说过它是一个指针:
var fptr: TFileType
但是你在传递一个指针给另一个指针:
fptr^
将对DLL函数的调用更改为
if (read_record( fptr, Key, Contents, Status) <> 0) OR (Status <> 0)
(我认为你的测试结果实际上应该是<> 0) AND (Status <> 0)
,但没有文件我不确定。)
如果你确实需要在将Contents
传递给DLL之前初始化它,你应该使用FillChar(Contents, SizeOf(Contents), #0)
(或ZeroMemory
)来这样做,顺便说一句。
作为一个额外的建议,您可以稍微简化您的代码(我选择stdcall
作为调用约定):
var
read_record : function( var fptr: TFILETYPE;
Key: Integer;
Contents: PAnsiChar; // function fills this in
var Status: Integer): Integer stdcall;
var
Contents: AnsiString;
...
begin
SetLength(Contents, 100);
if (read_record(fptr, Key, PAnsiChar(Contents), Status)...
....
end;
相关文章:
- 当我使用 C++ 中的 C# dll 来使用 Selenium 时,存在异常处理问题
- 加载与引用 .NET DLL 位于同一文件夹中的引用的 .NET DLL 时"Not found"异常
- 在 ******.exe 中0x00000000772CA267 (ntdll.dll) 处未处理的异常:0xC0000
- 在类 12.exe 中0x7B37FF80 (ucrtbased.dll) 引发异常: 0xC0000005:访问冲突读
- 发生此错误:在0x0F2BFB7C(基于.dll)时引发异常 尝试更改大小是问题吗?
- 为什么g_object_set抛出异常(vcruntime140.dll)?
- 处理 c++ DLL 的异常
- 在OpenCV_core310.dll中使用findContours函数时,OpenCV引发未处理的异常
- 在 Project70.exe 中的0x0F4D514F (vcruntime140d.dll) 引发异常:0xC000
- 在0x5914F3BE抛出异常(基于.dll)
- 使用 C++ dll 运行 c# 应用程序会生成无法加载异常
- 核心消息传递中未处理的异常.dll在程序关闭期间
- 在 Hello World.exe 中0x0F828F0E (ucrtbased.dll) 处未处理的异常: 0xC00
- Windows错误:异常:使用从C++到Python的ctypes创建DLL时出现访问冲突或Windows错误193
- 如何在C++中修复PyImport_Import(python35.dll中的异常)
- 加载C DLL文件时,如何修复异常_access_violation
- 实验室中0x6BE20E11 (ucrtbased.dll) 的未处理异常.exe: 0xC0000005:访问冲突读取
- 在 "<name>.exe" 中0x00007FFF168E1657 (vcruntime140d.dll) 引发异常:0xC0000005:访问冲突写入位置0x0000000000000
- mystring.exe中的0x0FC9E559(ucrtbaseed.dll)的未经手法异常:0xc0000005:访
- C++Windows DLL:不同函数中的异常处理