Her*_*lez -4 delphi dll external lazarus lib
我在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;
}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
程序在运行时调用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.
Run Code Online (Sandbox Code Playgroud)
如果我注释掉该行{$Link GLib.lib},程序就会运行,但是当我调用时它会一直崩溃GRFLoad(程序停止工作然后关闭).如果我留{$Link GLib.lib}在行中,程序不会编译并报告错误:
project1.lpr(20,1)错误:读取GLib.lib时非法COFF Magic
任何提示?
注意:我刚刚添加了一个Visual C++ 2010项目的链接,其中包含所有需要的文件.事实上,我刚刚制作了一个"新项目 - > Win32控制台应用程序"(我在向导中标记"空项目"),添加新的CPP文件并粘贴代码,然后更改"属性 - >配置属性 - >链接器 - >启用增量链接:否",即全部.
https://drive.google.com/open?id=1JxW4Wra_kT8gfBda1t0WWqagzazzQVne
函数的正确声明将使用a PAnsiChar(char在C和C++中始终是单字节类型):
type
GFile = Pointer; // alternatively: GFile = THandle;
function GrfLoad(const FName: PAnsiChar; Mode: Boolean): GFile; cdecl; external 'GLib.dll' name 'GrfLoad';
procedure grfFree(GVar: GFile); cdecl; external 'GLib.dll' name 'GrfFree';
Run Code Online (Sandbox Code Playgroud)
但是,这是非常有可能的是,导出的名称不GrfLoad和GrfFree,但不同的名称,如_GrfLoad和_GrfFree.您可以使用MS的Dependency Walker等工具或使用Delphi自己的TDump.exe(查找"导出"部分)找出实际导出的名称,即使用
tdump glib.dll
Run Code Online (Sandbox Code Playgroud)
在glib.dll所在目录的命令行上.
如果名称不同,那么您将不得不更改外部声明的名称部分,例如external 'Glib.dll' name '_GrfLoad';,等等.
我的文章中的更多信息:转换的陷阱.
当然,DLL也可能找不到它所依赖的另一个DLL.Dependency Walker还会告诉您缺少的进口.
请注意,您链接到的zip文件中的DLL称为GrfLib.dll,而不是GLib.dll.这些名字确实是出口GrfLoad等等.
很可能你的系统上也有glib.dll,但是它不包含你正在寻找的功能.
另请注意,大多数人不喜欢从未知来源下载zip.他们无法知道其中的真实含义.