【问题标题】:Calling DLLs with pointers in Delphi在 Delphi 中使用指针调用 DLL
【发布时间】:2011-01-25 20:08:47
【问题描述】:

我是德尔福的新手。我有一个 DLL,其中包含以下导出函数:

bool __stdcall MyFunction(char * name, int * index)  

在 C++ 中调用这个 DLL 函数的代码完美运行:

typedef void (WINAPI * MyFunction_t)(char *, int *);
void main()
{
    HMODULE mydll = LoadLibrary(L"C:\\mydll.dll");
    MyFunction_t MyFunction = (MyFunction_t)GetProcAddress(mydll, "MyFunction");

    int index = 0;

    MyFunction("MyString", &index); 
}

我需要在 Delphi 中做同样的事情。这是我的代码,它不起作用(调用了 MyFunction 但索引变量没有收到适当的值)。这是一个代码摘录,所以请忽略混乱。任何意见将不胜感激!

type
  TMyFunction= function(name: PChar; var index_ptr: Integer): Boolean; stdcall;

var
  fMyFunction : TMyFunction;
  i : Integer;
  h: THandle;

begin
  Result := 0;
  h := LoadLibrary('c:\\mydll.dll');
  fMyFunction := GetProcAddress(h, 'MyFunction');
  if @fMyFunction <> nil then
  begin
    fMyFunction('MyString', i);
    Result := i;
  end;
  FreeLibrary(h);
end;

【问题讨论】:

  • 你的 dll 是用什么语言构建的?
  • 你的 C 代码调用了一个 'void' 函数,但 Delphi 代码调用了一个返回布尔值的函数...?
  • @Roddy 这是调用函数的 C 代码中的一个问题,但它似乎是良性的,因为这些代码都没有对返回值做任何事情

标签: delphi dll pointers


【解决方案1】:

首先我假设您正在使用与extern "C" 的C 链接,以防此函数在C++ 翻译单元中定义。

如果您使用的是 Delphi 2009 或更高版本,则需要注意 PChar 是指向以 null 结尾的 wide 字符串的指针。

要与您的 ANSI C 函数进行互操作,您需要使用:

type
  TMyFunction= function(name: PAnsiChar; var index: Integer): Boolean; stdcall;

C bool 类型可能最好映射到 LongBool,因为它与 Delphi Boolean 不太一样:

type
  TMyFunction= function(name: PAnsiChar; var index: Integer): LongBool; stdcall;

您无需在字符串中转义\,因此您可以编写:

h := LoadLibrary('c:\mydll.dll');

您可能应该在调用 LoadLibrary 时检查错误,从技术上讲,hHMODULE 而不是 THandle,尽管这不会给您带来任何问题。

地道的 Delphi 会这样写:

  if Assigned(fMyFunction) then
    fMyFunction('MyString', Result);

对我来说基本上它看起来很合理,但我最怀疑字符宽度。

希望对您有所帮助。

【讨论】:

  • 很好的答案,我对 C/C++ 不太擅长,但不应该将 TMyFunction 定义为 TMyFunction= function(name: PAnsiChar; index: PInteger): LongBool;标准调用;因为导出的函数被定义为 int *index?
  • @dorin 这取决于。如果它是一个可选参数,那么它应该按照您建议的方式完成。否则最好作为 var 参数。
  • 这个函数被定义为 bool __stdcall MyFunction(char * name, int * index),所以我怀疑 name 和 index 是强制性的,但无论如何,这表明 C++ 也是神秘的:-\
  • @dorin 不,您无法从代码签名中看出。也可以是。看看 msdn 中的一些 api 文档,看看一些指针参数是如何标记为 [in, opt] 的,而其他的只是 [in]。
  • 您应该始终编写 PAnsiChar,它适用于旧版本的 delphi,并且不需要在升级时/如果升级。 OP 还没有说他使用的是什么版本的 delphi。
【解决方案2】:

尽量不要在您的 TMyFunction 类型中使用 STDCALL。

【讨论】:

  • 另一件事:您最好为输入字符串“MyString”分配一个 Pchar 变量。声明一个 Pchar 变量,在其上设置“MyString”字符串并将变量传递给 dll。可能因为这个原因 dll 引发了异常。
  • 这样传递 PChar 完全没问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
相关资源
最近更新 更多