[笔记]Delphi 2007写DLL供VC调用实例

考虑如下几种常用情况:

- VC传入int,返回int

- VC传入char *,返回int

- VC传入char *,返回char *及int

为简化问题,传递的字符串参数只考虑ANSI格式,不考虑UNICODE。

如果需要UNICODE,可以自行使用字符串格式转换函数。

Delphi 2007的代码如下:

library DemoDll;

uses
  SysUtils, Classes, Windows, StrUtils;

{$R *.res}

// Write to log file
procedure AddLog(const AFormat: string; Args: array of const); overload;
var
  LogFile: TextFile;
  FileName: string;
begin
  FileName := GetEnvironmentVariable('TEMP') + '\DemoDll.log';
  try
    AssignFile(LogFile, FileName);

    if FileExists(FileName) then
      Append(LogFile)
    else
      ReWrite(LogFile);

    Writeln(LogFile, Format('[%s] ', [DateTimeToStr(Now)]) + Format(AFormat, Args));
  finally
    CloseFile(LogFile);
  end;
end;

// Write to log file
procedure AddLog(const AFormat: string); overload;
begin
  AddLog(AFormat, []);
end;

// return a+b
function TestAdd(a, b: Integer): Integer; stdcall;
begin
  AddLog('TestAdd(%d,%d)', [a, b]);
  Result := a + b;
end;

// do nothing, just log input string
function TestInputStr(PInStr: PChar): Integer; stdcall;
var
  str: string;
begin
  str := StrPas(PInStr);
  AddLog('TestInputStr(%s)', [str]);
  Result := 0;
end;

// reverse first string and write to second string
function TestOutputStr(PInStr, POutStr: PChar): Integer; stdcall;
var
  str: string;
begin
  str := StrPas(PInStr);
  str := ReverseString(str);
  StrCopy(POutStr, PChar(str));
  AddLog('TestOutputStr(%s)', [str]);
  Result := 0;
end;

exports
  TestAdd,
  TestInputStr,
  TestOutputStr;

begin
  AddLog('BEGIN');
end.

  

VC2013的代码如下:

// Put DemoDll.dll in the same dir
// DemoDll.dll is developed by Delphi

#include "windows.h"
#include <iostream>

typedef int(__stdcall  *fTestAdd)(int, int);
typedef int(__stdcall  *fTestInputStr)(char *);
typedef int(__stdcall  *fTestOutputStr)(char *, char *);

using namespace std;

int main(int argc, char* argv[])
{
    HINSTANCE       hDllLibrary = NULL;
    
    fTestAdd        TestAdd = NULL;
    fTestInputStr   TestInputStr = NULL;
    fTestOutputStr  TestOutputStr = NULL;
    
    hDllLibrary = LoadLibraryA("DemoDll.dll");
    if (hDllLibrary){
        TestAdd = (fTestAdd)GetProcAddress(hDllLibrary, "TestAdd");
        TestInputStr = (fTestInputStr)GetProcAddress(hDllLibrary, "TestInputStr");
        TestOutputStr = (fTestOutputStr)GetProcAddress(hDllLibrary, "TestOutputStr");

        // check if a == 3
        int a = TestAdd(1, 2);
        cout << "TestAdd(1,2)=" << a << endl;

        // check if input string has output to log file
        char b[] = "nothing";
        TestInputStr(b);
        cout << "TestInputStr(" << b << ")" << endl;

        // check if output string is reversed
        char c[] = "nothing";
        char d[256] = { 0 };
        TestOutputStr(c, d);
        cout << "TestOutputStr(" << c << ")=" << d << endl;
    }

    getchar();
    return 0;
}

// Console output:
//
// TestAdd(1, 2) = 3
// TestInputStr(nothing)
// TestOutputStr(nothing) = gnihton
//
// %Temp%/DemoDll.log
//[2017 / 6 / 4 14:48 : 46] BEGIN
//[2017 / 6 / 4 14:48 : 46] TestAdd(1, 2)
//[2017 / 6 / 4 14:48 : 46] TestInputStr(nothing)
//[2017 / 6 / 4 14:48 : 46] TestOutputStr(gnihton)