3

C++ で DLL を作成し、関数をエクスポートしようとしています。

これは私のC++コードです:

#include <Windows.h>

void DLLMain(){

}

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

これは私のデルファイコードです:

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」のメッセージボックスが表示されます。しかし、後で「機能がロードされていません」と表示されます。ここで何が間違っていますか?

4

2 に答える 2

6

これをC関数(__cdecl)としてエクスポートして、exportsテーブルに適切な名前を付けることができます。

名前装飾規則:Cリンケージを使用する__cdecl関数をエクスポートする場合を除いて、名前の前にアンダースコア文字(_)が付きます。

したがって、基本的に、関数の名前xMainはexportsテーブルにあります。

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;
于 2012-11-26T04:47:36.127 に答える
2

呼び出し規約を使用して関数をエクスポートし(特に、Delphi__stcallの呼び出し規約を使用してインポートしようとしているため)、エクスポートされた名前の装飾を削除するために使用します。stdcallextern "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.
于 2012-11-26T22:07:32.497 に答える