在jna句柄和字符串中映射delphi/pascal dll的函数 [英] function mapping delphi/pascal dll in jna handle and string

查看:244
本文介绍了在jna句柄和字符串中映射delphi/pascal dll的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 JNA 在delphi dll中调用函数.函数定义为:

I'm trying to call a function in a delphi dll using JNA. the function definition is:

function myFuncGetName (aHandle : THandle; var aBuf : pwideChar ): integer; export;

我的jna映射如下:

int myFuncGetName(PointerByReference aHandle, WString aBuf);

对于成功,返回值应该为0,对于失败,返回值为-1,我总是得到-1.

the return value should be 0 for success and -1 for fail and I'm always getting -1.

我已经启动WinDbg并附加到该进程,它在myFuncGetName处中断.

I have started up WinDbg and attached to the process and it breaks at myFuncGetName.

057cb384 eb11            jmp     myDLL!myFuncGetName+0x87 (057cb397)
057cb386 b8dcb37c05      mov     eax,offset myDLL!myFuncGetName+0xcc (057cb3dc)
057cb38b 8b55f8          mov     edx,dword ptr [ebp-8]
057cb38e 8902            mov     dword ptr [edx],eax  ds:002b:00000000=???????? <-- ### breaks here ###
057cb390 c745f4ffffffff  mov     dword ptr [ebp-0Ch],0FFFFFFFFh

我不是程序集向导,所以请在错误的地方纠正我. 我认为其将地址(函数自变量)从位置ebp-8移至edx寄存器. ebp-8指向值0,因此edx为0. 它将eax移到edx指向的地址. 它不应该将任何内容移动到0,所以都坏了吗?

I'm not an assembly wiz so correct me where I'm wrong. I think its moving an address (function argument) from location ebp-8 to the edx register. ebp-8 points to value 0 so edx is 0. it moves eax to address pointed by edx. Its not supposed to move anything to 0 so it all breaks?

为什么我的参数没有正确传递给函数? 我从上一次调用的同一个DLL中获得了aHandle,并将aBuf设置为 WString aBuf = new WString("placeholderstring"); 我希望函数返回后,aBuf会用真实文本填充.

Why aren't my arguments correctly passed to the function? I get aHandle from the same DLL from a previous call and I set up aBuf as WString aBuf = new WString("placeholderstring"); I expect aBuf to be filled with real text after the function returns.

这一切都在Windows 7上使用Java 7 64bit运行.该DLL是32位DLL.

This is all running on Windows 7 with java 7 64bit. The DLL is a 32bit DLL.

更新和解决方案:

谢谢David和Rob的评论.我已经更改了delphi定义以使用stdcall声明.现在,调用该函数将返回0.要检索pwideChar的值,我执行了以下操作:

Thank you David and Rob for your comments. I have changed the delphi definition to use the stdcall declaration. Calling the function now returns 0 which it should. To retrieve the value of the pwideChar I did the following:

int charcount= "placeholder".length();
PointerByReference aBuf = new PointerByReference(new Memory(charcount*4));
int returnvalue = myFuncGetName(aHandle, aBuf);
if(returnvalue == 0) {
    System.out.println(aBuf.getValue().getString(0, true));
}

推荐答案

如果这是DLL函数的真正声明,则问题可能出在调用约定上. Delphi中的默认调用约定为register,它将前两个参数存储在EAX和EDX中,但是默认的C调用约定为cdecl,将其存储在堆栈中.将Delphi声明更改为此:

If that's the real declaration of the DLL function, then the problem could be the calling convention. The default calling convention in Delphi is register, which stores the first two arguments in EAX and EDX, but the default C calling convention is cdecl, which stores them on the stack. Change the Delphi declaration to this:

function myFuncGetName(aHandle: THandle; var aBuf: PWideChar): Integer; stdcall;

(export指令实际上不再做任何事情(我认为从Delphi 2开始),因此可以将其删除.它已被exports子句所包含,您可以在DLL的其他位置找到它.来源.)

(The export directive doesn't really do anything anymore (as of Delphi 2, I think), so you can remove it. It's been subsumed by the exports clause, which you should find elsewhere in the DLL source.)

Java方面也是错误的. Delphi代码中的第二个参数是对PWideChar引用.我在JNA中看不到WStringByReference类型,但这就是您所需要的.不过,我无法提供有关如何自己实施的任何建议.

The Java side is also wrong. The second parameter in the Delphi code is a reference to a PWideChar. I see no WStringByReference type in JNA, but that's what you'll need. I can't offer any advice on how to implement it yourself, though.

这篇关于在jna句柄和字符串中映射delphi/pascal dll的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆