gpt4 book ai didi

delphi - 获取和删除在 DLL 中创建的对象

转载 作者:行者123 更新时间:2023-12-03 19:37:08 26 4
gpt4 key购买 nike

我有一个用 C++ 编写的 dll。它看起来像这样:

头文件:

#define DllExport extern "C" __declspec( dllexport )

#include "SpeedTreeRT_1_8.h"

DllExport CSpeedTreeRT* NewSpeedTree(void);
DllExport void DeleteTree(CSpeedTreeRT* handle);
DllExport bool LoadTree(CSpeedTreeRT* handle, const unsigned char* pBlock, unsigned int nNumBytes);

cpp文件:
CSpeedTreeRT* NewSpeedTree(void) {
return new CSpeedTreeRT();
}

void DeleteTree(CSpeedTreeRT* handle) {
delete handle;
}

bool LoadTree(CSpeedTreeRT* handle, const unsigned char* pBlock, unsigned int nNumBytes) {
return handle->LoadTree(pBlock, nNumBytes);
}

Delphi 类型定义:
TNewSpeedTreeFunc = function (): Cardinal; cdecl;
TLoadTreeFunc = function (AHandle: Cardinal; const ABlock: String; ANumBytes: Cardinal): Boolean; cdecl;
TDeleteTreeFunc = procedure (AHandle: Integer); cdecl;

然后我使用 LoadLibrary 将 dll 加载到 delphi 应用程序中。
DllHandle: Cardinal;
NewSPeedTreeFunc : TNewSpeedTreeFunc;
LoadTreeFunc: TLoadTreeFunc;
DeleteTreeFunc: TDeleteTreeFunc;

DllHandle := LoadLibrary('SpeedTreeFT.dll');

@NewSpeedTreeFunc := GetProcAddress(DllHandle, 'NewSpeedTree');
@LoadTreeFunc := GetProcAddress(DllHandle, 'LoadTree');
@DeleteTreeFunc := GetProcAddress(DllHandle, 'DeleteTree');


SpeedTreeHandle := NewSpeedTreeFunc;

... call other functions here ...

DeleteTreeFunc(SpeedTreeHandle);

FreeLibrary(DLLHandle);

Dll 导出除了 LoadTree 之外的其他函数,为了清楚起见,我只是删除了它们。

发生的情况是,如果我运行一次,一切正常,我可以调用 dll 中的其他函数并得到预期的结果。当我第二次运行它时,我在调用 NewSpeedTree 时遇到访问冲突异常。我还注意到对 DeleteTree 的调用不会从应用程序中释放内存。

我在dll中以正确的方式做吗?什么可能导致这个问题?

EDIT1:在代码块中提供了更多信息。

最佳答案

最大的问题似乎是您声明 pBlock作为 string !

声明:

bool LoadTree(CSpeedTreeRT* handle, const unsigned char* pBlock, unsigned int nNumBytes);

应译为:
type
TLoadTreeFunc = function(Handle: THandle; const pBlock: PByte;
nNumBytes: Cardinal): LongBool cdecl;
unsigned charByte ,指向它的指针是 PByte .要使用它,只需将指针传递给您保留的 block 的第一个字节(例如, TBytes 已设置为适当的长度,使用 SetLength )。

就像是:
var
Block: TBytes;
begin
SetLength(Block, the_required_length);
if LoadTree(SpeedTreeHandle, @Block[0], Length(Block)) then
// etc...

将类型字符串传递给(非 Delphi)DLL
string是 Delphi 类型,在 Delphi 2009 或更高版本中,它甚至是 UnicodeString .但即使是 2009 年之前,其中字符串是 AnsiString ,通过它是错误的。两个 AnsiStringUnicodeString Delphi 特有的,不能用作用 C++ 编写的 DLL 的参数类型 .所以永远不要声明 char *unsigned char *string , 但始终为 PAnsiCharPByte分别。

我的这些文章中的更多信息: "DLL dos and don'ts""Pitfalls of converting" .

关于delphi - 获取和删除在 DLL 中创建的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49613463/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com