- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直坚持调用外部 DLL 并传递函数(指针)作为参数。我最近在向 DLL 传递一些参数时遇到了不同的问题,你提供了帮助。希望,有人也知道如何做到这一点......
下面是需要从 Delphi 调用的 DLL (cpp) 中的函数声明:
typedef void (*PTR_Allocate)(char**, unsigned long*);
typedef void (*PTR_Deallocate)(char*);
extern "C" export_dll_function void SetAllocateFunction(PTR_Allocate);
extern "C" export_dll_function void SetDeallocateFunction(PTR_Deallocate);
void Allocate(char** pbuffer, unsigned long* psize)
{
*psize = *psize * 2;
*pbuffer = new char[*psize];
}
void Deallocate(char* buffer)
{
delete[] buffer;
}
您能帮我用 Delphi (7) 重写这个吗?
这是我尝试过的方法,它引发了异常(“外部异常”):
type
PByte = ^TByte;
TByte = array of byte;
TFunc = function(var pbuffer: PByte; var psize: Cardinal): integer; cdecl;
Procedure _SetAllocateFunction(var f: TFunc); cdecl;
implementation
function Allocate(var pbuffer: PByte; var psize: Cardinal): Integer; cdecl;
begin
psize := psize * 2;
GetMem(pbuffer, psize);
end;
var Func: TFunc;
Func := @Allocate;
_SetAllocateFunction(Func);
非常感谢!
最佳答案
如果您不确定自己在做什么,请始终从最直白的翻译开始。函数原型(prototype)表示它接收一个指向 char 的指针,所以这就是您应该使用的:
type
PTR_Allocate = procedure(param1: ^^Char; param2: ^LongWord); cdecl;
一旦您确定它是正确的,然后开始用更类似于 Delphi 的等效项替换内容。如果您跳过第一步,您可能永远不会做对,因为您只会不断地对开始时错误的内容进行更改。
那么,您确定以上内容正确吗?不完全的。 Delphi 中的 Char
根据产品版本的不同可以有不同的含义。您正在使用 Delphi 7,但您可能会升级,因此您可能会与其他人共享此代码,因此您应该明确您想要的 Char 大小。当您需要一字节类型时,请使用 AnsiChar。
type
PTR_Allocate = procedure(param1: ^^AnsiChar; param2: ^LongWord); cdecl;
现在我们可以开始让它看起来更像 Delphi。一级指针参数可以用“var”或“out”指令替换。对每个参数执行此操作:
type
PTR_Allocate = procedure(out param1: ^AnsiChar; var param2: LongWord); cdecl;
AnsiChar 指针是一种非常常见的类型,Delphi 已经为它起了一个名字:PAnsiChar。使用惯用名称:
type
PTR_Allocate = procedure(out param1: PAnsiChar; var param2: LongWord); cdecl;
最后,您可能希望对涉及角色的整个概念采取一些自由。您显然正在为任意字节缓冲区分配内存,因此 Byte 可能是比任何字符类型更好的选择。最近的 Delphi 版本声明了一个指向字节类型的指针,因此使用它:
type
PTR_Allocate = procedure(out param1: PByte; var param2: LongWord); cdecl;
<小时/>
现在进入SetAllocateFunction
。它说它接收一个PTR_Allocate
参数,它是一个指向函数的指针。 Delphi 的过程类型是隐式指针,因此我们上面声明的类型对于 Delphi 等效项来说已经完全正确。不要使用额外的“var”指令通过引用传递它,否则即使在程序尝试分配任何内存之前,您也会遇到您所看到的问题。这是其他答案忽略的事情。
procedure SetAllocateFunction(param: PTR_Allocate); cdecl;
也不要在名称开头添加下划线,除非您想让在您自己的代码中调用不方便。如果它使用不同的名称从 DLL 导出,则在编写函数的实现时使用“name”子句:
procedure SetAllocateFunction; extern 'foo.dll' name '_SetAllocateFunction';
<小时/>
最后,如何实现分配功能。从与 PTR_Allocate 签名匹配的内容开始,然后继续使用原始 C++ 代码的尽可能字面的翻译来实现它。
procedure Allocate(out pbuffer: PByte; var psize: LongWord; cdecl;
begin
psize := psize * 2;
GetMem(pbuffer, psize);
end;
可以用之前的函数来设置:
SetAllocateFunction(Allocate);
请注意,我不需要单独的变量,也没有使用 @
运算符。如果您需要使用 @
运算符来提及函数指针,在大多数情况下,您就做错了。你通常不需要它。使用该运算符可以隐藏程序中的错误,例如签名不匹配,因为默认设置是@
运算符无类型。使用它会从函数指针中删除类型,并且无类型指针与 Delphi 中的所有内容兼容,因此它们适合任何其他函数指针类型,包括签名错误的类型。
仅当编译器已表明它已尝试调用函数时,才在函数指针上使用@
,例如通过提及您如何没有足够的参数或通过提及函数的返回类型。
关于delphi - (Delphi) 用函数指针参数调用DLL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1819180/
请在标记为重复之前阅读。 我正在创建一组依赖智能卡进行身份验证的应用程序。到目前为止,每个应用程序都单独控制智能卡读卡器。几周后,我的一些客户将同时使用多个应用程序。因此,我认为创建一个控制身份验证过
我想设置一个小程序,从数据库中检索信息,然后根据请求将该信息分发给另一个程序。例如,一个名为“Master”的程序将从数据库中检索数据并创建一个对象集合(列表、数组等,无论哪种效果最好),然后一个名为
我有两台电脑,都装有 XE2。我以为我在两者上安装了相同的安装,但在其中一个上安装第 3 方软件包时遇到问题,而另一个则正常。 无论如何,我希望两者都一样。最简单的人可能只是通过移入我的 Dropbo
有冲突吗? 最佳答案 所有新版本的 Delphi 始终可以安全地安装到旧版本的下一个版本。 每个新版本都应安装在其自己的目录中。 如果您要安装多个版本,请始终先安装最旧的版本,然后再安装最新版本。 我
快速提问:如果我从代码中删除 // 或 (* *) 中的注释,Delphi 2007 的执行时间会受到影响吗?最终结果是一个可能包含数千行注释的 EXE 文件。 最佳答案 编译器会简单地忽略注释,并且
我必须对照另一个文件检查文件的每一行。 如果第二个文件中存在第一个文件中的一行,则必须删除它。 现在,我正在使用2个列表框,并且“对于listbox1.items.count-1可以开始...” 我的
我正在尝试在访问数据库中添加一些数据。但是我有麻烦,因为这会返回错误: ADOQuery1 missing sql property 实现了对代码的几次修改,到目前为止没有任何效果。 我究竟做错了什么
我用Delphi 5编写了一个程序,在Windows 8 32位PC上可以正常运行。我发现在Windows 7 64位笔记本电脑上运行它最终会导致reallocmem错误,而该错误在32位PC上不会发
看来这是我需要的工具,用于提取XML并与TClientDataset连接。我已经在几篇文章和文档中看到了它,但是我无法在XE2组件列表中找到它-在任何地方!应该在哪里?是否在可能未安装的可选软件包中?
我正在寻找一个非常通用的TDBTree组件,我想听听一些建议。我正在特别寻找一种显示主记录和“ n”个链接表记录的记录。 (我的意思是来自各个表的记录)。例如,TDBTree将钩接到主表,明细表1,附
我需要将按钮制作成旋转三角形的形状(或者说是任何多边形)。谁能提供任何建议? 最佳答案 查看Win32 API CreatePolygonRgn()和SetWindowRgn()函数,以创建一个HRG
你好专家 我的JvPasswordForm1有一个旧的JVC组件。 似乎该组件不再存在:它替换为哪个组件? 重新获得 最佳答案 尝试查找TJvLoginDialog,TjvPassword已合并到其中
几天前,我已经设置了我的开发环境(在装有Win 7的VM和域上的用户的VM上安装了delphi 2009),并安装了我的组件(jedi's,devExpress,ADS等)。 今天,我启动机器,打开d
开始对控件进行子分类的正确位置/时间是什么? 恢复原始窗口proc的正确时间是几点? 现在我在表单创建过程中子类化: procedure TForm1.FormCreate(Sender: TObje
有人可以给我一些有关如何登录访问的网页(使用任何网络浏览器)的指示吗?我应该建立一个全球代理....钩住网络....吗?我需要记录的只是页面地址,而不是其中包含的信息。 我正在使用Delphi。 谢谢
我创建了一个像 TMyClass = class(TObject) private FList1: TObjectList; FList2: TObjectList; public end;
我有一个BPG文件,我已对其进行修改以用作我们公司的自动构建服务器的make文件。为了使其正常工作,我必须进行更改 用途*用途 'unit1.pas'中的unit1 * unit1 'unit2.pa
我将Delphi 7代码迁移到了Delphi XE4。我在Delphi XE4的LoadFromStram方法中遇到错误,但对于Delphi 7来说也可以正常工作。 错误: First chance
我正在尝试学习一些新技巧,以便更好地组织我在 Delphi 中的单元中的一些源代码。 我注意到我访问的一些函数或方法似乎是类中的类,但是我还没有成功地在类中创建一个工作类,虽然它编译得很好,但在执行代
我有一个包含许多类的大单元,现在我想通过将某些类分成新的单元来重构该单元。 我不得不承认我缺乏使用Delphi内置IDE功能的经验。利用内置功能“查找|查找对类型的本地引用”并没有多大帮助,因为类方法
我是一名优秀的程序员,十分优秀!