【发布时间】:2018-08-10 18:13:56
【问题描述】:
我有这段 C 代码,我想移植到 Delphi,但我无法让它工作。
.CPP 代码
#include <Windows.h>
#include <io.h>
#include <stdio.h>
#include "GLibExp.h"
#pragma comment(lib, "GLib.lib")
void MyCFunc(LPCTSTR GStr)
{
GFile GVar = NULL;
GVar = GrfLoad(GStr, 1);
if ( !GVar )
{
printf("Error during loading!\n");
} else
printf("All fine!\n");
GrfFree(GVar);
system("pause");
}
void main()
{
CHAR StrG[MAX_PATH] = "Test.grf";
MyCFunc(StrG);
return;
}
GLibExp.h
#ifndef GLibExpH
#define GLibExpH
#if defined(GRF_DLL)
#define GEXPORT __declspec(dllexport)
#else
#define GEXPORT extern
#endif
class CGFILE;
typedef CGFILE* GFile;
//typedef void* GFile; //Also works like this
#ifdef __cplusplus
extern "C" {
#endif
GEXPORT GFile GrfLoad(const char *GName, unsigned char Mode = 1);
GEXPORT void GrfFree(GFile GVar);
#ifdef __cplusplus
}
#endif
#endif//GLibExpH
程序在运行时调用 DLL 以使用 GRFLoad 和 GRFFree 函数。我尝试将其移植到 Delphi,但没有成功。
德尔福/拉撒路代码:
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
{$Link GLib.lib}
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
function GrfLoad(const fname: PChar; Modo: Boolean): Pointer; cdecl; external 'GLib.dll';
procedure TForm1.Button1Click(Sender: TObject);
var
PVar: Pointer;
begin
PVar:= GrfLoad(PChar('test.grf'),false);
end;
end.
如果我注释掉{$Link GLib.lib} 行,程序会运行,但是当我调用GRFLoad 时它总是崩溃(程序停止工作然后关闭)。如果我留在{$Link GLib.lib}这一行,程序不编译并报错:
project1.lpr(20,1) Error: Illegal COFF Magic while reading GLib.lib
有什么提示吗?
注意:我刚刚添加了一个指向 Visual C++ 2010 项目的链接,其中包含所有需要的文件。其实我只是做了一个“New project -> Win32 Console Application”(我在Wizard中标记了“empty project”),添加一个新的CPP文件并粘贴代码,并更改“Properties -> Configuration Properties -> Linker - > 启用增量链接:否”,仅此而已。
https://drive.google.com/open?id=1JxW4Wra_kT8gfBda1t0WWqagzazzQVne
【问题讨论】:
-
运行时错误。 “程序停止工作”,然后关闭。
-
GEXPORT __declspec(dllexport)是否对应stdcall? -
不知道是否对应stdcall。 lib已编译,没有源代码。
-
你绝对不需要
GLib.lib。 DLL 的失败有一些原因 - 由于名称修改、错误的校准约定、错误的参数描述、内存处理问题(不同的内存管理器、使用内部 Delphi 托管类型 lke 字符串)导致的错误导入名称。似乎第一个不是你的情况 - 加载过程中关于错误名称的静态导入报告。 -
@Victoria 不,C 和 C++ 编译器的默认调用约定将是 cdecl
标签: delphi dll external lazarus lib