【问题标题】:Strange behaviour in Delphi dynamic DLL callDelphi动态DLL调用中的奇怪行为
【发布时间】:2017-01-12 00:11:58
【问题描述】:

我有以下问题:

我有一个用 C++ 编写的 DLL,它接受输入参数为 * char。

使用 Delphi RTL 以下列方式声明 DLL 时:

function MyDllCall(aParam: PAnsiChar): Longint; stdcall; external 'MyDllName.dll' name 'MyFunction'

并从我的代码中调用它:

MyDllCall(PAnsiChar('some text'));

效果很好。

当我尝试通过调用 LoadLibrary、GetProcAddress 和 FreeLibrary 来调用它时,如下代码所示:

procedure DllCall;
type
  TMyDllCall = function(aParam: PAnsiChar): Longint;
var
  aMyDllCall: TMyDllCall;
  libHandle: Integer;
  res: Integer; 
begin
  libHandle := LoadLibrary('MyDLL.dll');
  if libHandle <> 0 then
  begin
    @aMyDllCall := GetProcAddress(libHandle, 'MyDllFunction');
    if @aMyDllCall <> nil then
    begin
      res:= aMyDllCall(PAnsiChar('some text')); << This crashes
      FreeLibrary(libHandle);
    end;
  end;
end;

我相信这个问题在某种程度上与作为 PAnsiChar 传递的字符串参数有关。试图更改 C++ dll 源代码注销参数并验证分配的参数变量中的一些奇怪文本。

编辑:下面是 C++ Dll 代码的一部分:

#include "stdafx.h"

#pragma once  

#define MYDLLLIBRARY_API extern "C" __declspec(dllexport)   

MYLIBRARY_API DWORD WINAPI MyDllFunction(char * dirname);

DWORD WINAPI MyDllFunction(char * dirName){
    return someFunction(dirName);
}

void getFileNames(char * workingDir){

    HANDLE hFind;
    WIN32_FIND_DATAA data;
    char nextfilename[260];
    sprintf(nextfilename, "%s*.jpg", workingDir);
    hFind = FindFirstFileA(nextfilename, &data);
    if (hFind != INVALID_HANDLE_VALUE) {
        do {
            if (strlen(data.cFileName) < 3) continue;
            char tmp[260];
            sprintf(tmp, "%s%s",workingDir, data.cFileName);
            filenames.push_back(tmp);
        } while (FindNextFileA(hFind, &data));
        FindClose(hFind);
    } else{

        exit(0);
    }
}

int MyDllFunction(char* workingDir)
{
    ...
    getFileNames(workingDir);
    ...
}

我错过了什么吗? 谢谢。

【问题讨论】:

  • 也发布 C++ DLL 代码。
  • 您似乎在第二个代码 sn-p 中缺少 stdcall?
  • 完成!这就是我所缺少的!感谢您的帮助。
  • 您不需要将文字转换为 PAnsiChar 并且如果可能的话,加载 DLL 一次而不是每次您想要调用函数时。

标签: c++ delphi dll


【解决方案1】:

您的第一个定义(静态的)使用stdcall

function MyDllCall(aParam: PAnsiChar): Longint; stdcall; external Stdcall 'MyDllName.dll' name 'MyFunction';

您的第二个(动态)没有。由于这是失败的原因,我认为很明显缺少stdcall 是问题所在:

type
  TMyDllCall = function(aParam: PAnsiChar): Longint;  // No stdcall here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-03
    • 1970-01-01
    • 1970-01-01
    • 2017-12-13
    • 2015-04-20
    • 1970-01-01
    • 2021-07-28
    相关资源
    最近更新 更多