如何从C ++ DLL导出函数并在delphi中使用?

时间:2012-11-26 04:10:18

标签: c++ delphi dll

我正在尝试用C ++创建一个DLL并导出一个函数。

这是我的C ++代码:

#include <Windows.h>

void DLLMain(){

}

__declspec(dllexport) void xMain(){
MessageBox(NULL,L"Test",L"Test",NULL);
}

这是我的delphi代码:

program prjTestDllMain;

Uses
  Windows;

Var
  xMainPrc:procedure;stdcall;
  handle : THandle;
begin
    handle := LoadLibrary('xdll.dll');
    if handle <> 0 then
    begin
        MessageBox(0,'DLL Loaded', 0, 0);
        @xMainPrc := GetProcAddress(handle, 'xMain');
        if @xMainPrc <> nil then
            MessageBox(0,'Function Loaded', 0, 0)
        else
          MessageBox(0,'Function Not Loaded', 0, 0);
        MessageBox(0,'Process End', 0, 0);
        FreeLibrary(handle);
    end else
      MessageBox(0,'DLL Not Loaded', 0, 0);
end.

我收到“DLL Loaded”的消息框就好了。但之后我得到“功能未加载”。我在这里做错了什么?

2 个答案:

答案 0 :(得分:6)

您可以将其导出为C函数(__cdecl),以便在导出表上有一个很好的名称。

  

名称装饰惯例:   除了导出使用C链接的__cdecl函数时,下划线字符(_)以名称为前缀。

基本上,您的函数在exports表中将具有名称xMain

extern "C" __declspec(dllexport) void xMain()

在Delphi部分中,您只需指定cdecl并正常调用它:

var
  xMainPrc: procedure; cdecl;

例如:

if @xMainPrc <> nil then
begin
  MessageBox(0,'Function Loaded', 0, 0);
  xMainPrc;
end;

答案 1 :(得分:2)

使用__stcall调用约定导出函数(特别是因为您尝试使用Delphi中的stdcall调用约定导入它),并使用extern "C"删除任何导出的名称装饰:

<强> MyDll.h

#ifndef MyDLLH
#define MyDLLH

#ifdef __BUILDING_DLL
#define MYDLLEXPORT __declspec(dllexport)
#else
#define MYDLLEXPORT __declspec(dllimport)
#endif

#ifdef __cplusplus
extern "C" {
#endif

MYDLLEXPORT void __stdcall xMain();

#ifdef __cplusplus
}
#endif

#endif

<强> MyDll.cpp

#define __BUILDING_DLL
#include "MyDll.h"

#include <Windows.h>

void DLLMain()
{
}

void __stdcall xMain()
{
    MessageBox(NULL, L"Test", L"Test", NULL);
}

<强> prjTestDllMain.dpr

program prjTestDllMain;

uses
  Windows;

var
  xMainPrc: procedure; stdcall;
  handle : THandle;
begin
  handle := LoadLibrary('xdll.dll');
  if handle <> 0 then
  begin
    MessageBox(0,'DLL Loaded', 0, 0);
    @xMainPrc := GetProcAddress(handle, 'xMain');
    if @xMainPrc <> nil then
    begin
      MessageBox(0,'Function Loaded', 0, 0)
      xMainPrc();
    end else
      MessageBox(0,'Function Not Loaded', 0, 0);
    MessageBox(0,'Process End', 0, 0);
    FreeLibrary(handle);
  end else
    MessageBox(0,'DLL Not Loaded', 0, 0);
end.

可替换地:

<强> prjTestDllMain.dpr

program prjTestDllMain;

uses
  Windows;

procedure xMain; stdcall; extern 'MyDll.dll';

begin
  MessageBox(0,'DLL Loaded', 0, 0);
  xMain();
  MessageBox(0,'Process End', 0, 0);
end.