如何将C字符串传递给dll中的pascal函数 [英] How to pass a C string to a pascal function in a dll

查看:90
本文介绍了如何将C字符串传递给dll中的pascal函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好。

我有一个包含此功能的DLL:



函数DCL_Initialize(bDeviceID:Byte; sIP:PAnsiChar):字节; stdcall external'DCL.dll';



现在我想从C调用这个函数(稍微简化):

  #define DLL_EXPORT __declspec(dllexport)__stdcall 
typedef char DLL_IMPORT DCLINITIALIZE( char bDeviceId, char * pStr) ;
pString = 一些字符串;
DCLINITIALIZE * pfnInitialize =(DCLINITIALIZE *)GetProcAddress(hModule, DCL_Initialize);
if (pfnInitialize)
pfnInitialize( 1 ,pString);

函数没有返回。

我认为将字符串传递给C语言中的pascal例程可能需要特别考虑。

我对pascal的了解非常有限。我不知道什么是pAnsiChar;

有人能帮帮我吗?



编辑:

我我不确定该库是用pascal编写的。我唯一知道的是它的pascal原型,并且它正确地在delphi应用程序中工作。

pumpbin.exe / exports显示没有大写的功能名称



编辑2:字符串Software\Borland\Delphi\Locale在DCL.dll中找到好几次,所以它可能是由delphi创建的



Edit3 :线程遇到第一次机会异常并终止。但是delphi中的等效代码可以工作。唯一重要的是将char * sIP传递给

pascal函数。是char * in C与pascal中的PAnsiChar兼容吗?



编辑4:Visual Studio 2013的调试器和delphi的调试器显示不同的反汇编。贝娄显示了两者的一部分。差异由我的评论标记。

 / 11汇编指令 由delphi加载的DCL_Initialize  7  
0029B8E7 55 push ebp
0029B8E8 688ABA2900 push $ 688ABA2900
0029B8ED 64FF30 push dword ptr fs:[eax]
0029B8F0 648920 mov fs:[eax],esp
/ / 以下汇编指令是delphi中的两个字节,C中的4个字节,它们完全不同
0029B8F3 33DB xor eax,eax // 与C反汇编程序不同
0029B8F5 C605F0FF290000 mov byte ptr [$ 0029FFF0],$ 00
0029B8FC 33C0 xor eax,eax
0029B8FE 55 push ebp
0029B8FF 6863BA2C00 push $ 002CBA63
0029B904 64FF30 push dword ptr fs:[eax]
0029B907 648920 mov fs:[eax],esp
0029B90A 8A4508 mov al,[ebp + $ 08]
0029B90D E8FEFEFFFF电话 - $ 00000102
0029B912 85C0测试eax,eax
002CB914 740F jz + $ 0f


< span class =code-comment> // 由C加载的DCL_Initialize中的第11个汇编指令(由visual studio 2010或2013编译的调用者代码)
004D52C7 55 push ebp
004D52C8 68 0E 55 4D 00 按4D550Eh
004D52CD 64 FF 30 push dword ptr fs:[eax]
004D52D0 64 89 20 mov dwo rd ptr fs:[eax],esp
// 以下汇编指令在delphi中是两个字节,4 C中的字节,它们完全不同
004D52D3 C6 45 FF 00 mov byte ptr [ebp- 1 ], 0
004D52D7 C6 05 18 54 4E 00 00 mov byte ptr ds:[4E5418h], 0
004D52DE C6 05 20 54 4E 00 00 mov byte ptr ds:[4E5420h], 0
004D52E5 C6 05 19 54 4E 00 00 mov byte ptr ds:[4E5419h], 0
004D52EC 33 C0 xor eax,eax
004D52EE 55 push ebp
004D52EF 68 E5 54 4D 00 push 4D54E5h
004D52F4 64 FF 30 push dword ptr fs:[eax]
004B52F7 64 89 20 mov dword ptr fs:[eax],esp
004B52FA 8A < span class =code-digit> 45 08 mov al,byte ptr [ebp + 8]
004B52FD E8 FA FD FF FF调用039B50FC
004B5302 85 C0测试eax,eax
004B5304 74 11 je 039B5317

值得注意的是在delphi dll中使用fs segment寄存器。 delphi的PE模型是否持平?

Edit5:dumpbin / disasm生成的程序集与C反汇编完全匹配,与Delphi的反汇编不同。

解决方案

688ABA2900
0029B8ED 64FF30 push dword ptr fs:[eax]
0029B8F0 648920 mov fs:[eax], esp
// 以下汇编指令在delphi中是两个字节,在C中是4个字节,它们完全是不同
0029B8F3 33DB xor eax,eax // 与C反汇编程序不同
0029B8F5 C605F0FF290000 mov byte ptr


0029FFF0],


00
0029B8FC 33C0 xor eax,eax
0029B8FE 55 push ebp
0029B8FF 6863BA2C00推

Hello guys.
I have a DLL containing this function:

function DCL_Initialize(bDeviceID: Byte; sIP: PAnsiChar): Byte; stdcall external 'DCL.dll';

now I want to call this function from C as this(somewhat simplified):

#define DLL_EXPORT __declspec(dllexport) __stdcall
typedef char DLL_IMPORT DCLINITIALIZE(char bDeviceId, char *pStr);
pString = "Some string";
DCLINITIALIZE * pfnInitialize = (DCLINITIALIZE*)GetProcAddress(hModule, "DCL_Initialize");
if (pfnInitialize)
  pfnInitialize(1, pString);

The function doesn't return.
I think passing string to pascal routines from C may have special considerations.
My knowledge of pascal is very limited. and I don't know what is pAnsiChar;
Can anybody help me?

Edit:
I'm not sure the library is written in pascal. The only thing I know is its pascal prototype and that it works in a delphi application correctly.
pumpbin.exe /exports shows the names of funtions not capitalized

Edit2: string Software\Borland\Delphi\Locale found in DCL.dll several times, so it may be created by delphi

Edit3: The thread encounters a first chance exception and terminates. but the equivalent code in delphi works. the only thing to matter is passing char *sIP to
pascal function. is char * in C compatible to PAnsiChar in pascal?

Edit4: Visual studio 2013's debugger and delphi's debugger show different disassembly. Bellow is shown some part of both. The difference is marked by my comment.

/11th assembly instruction in DCL_Initialize loaded by delphi 7
0029B8E7 55         push ebp
0029B8E8 688ABA2900 push $688ABA2900
0029B8ED 64FF30     push dword ptr fs:[eax]
0029B8F0 648920     mov fs:[eax], esp
//The following assembly instruction is two byte in delphi, 4 byte in C, and they are entirely different
0029B8F3 33DB       xor eax, eax    //different from C disassembler
0029B8F5 C605F0FF290000 mov byte ptr [$0029FFF0], $00
0029B8FC 33C0       xor eax, eax
0029B8FE 55     push ebp
0029B8FF 6863BA2C00 push $002CBA63
0029B904 64FF30     push dword ptr fs:[eax]
0029B907 648920     mov fs:[eax], esp
0029B90A 8A4508     mov al, [ebp+$08]
0029B90D E8FEFEFFFF call -$00000102
0029B912 85C0       test eax, eax
002CB914 740F       jz +$0f


//11th assembly instruction in DCL_Initialize loaded by C(Caller code compiled by visual studio 2010 or 2013)
004D52C7 55                   push        ebp
004D52C8 68 0E 55 4D 00       push        4D550Eh
004D52CD 64 FF 30             push        dword ptr fs:[eax]
004D52D0 64 89 20             mov         dword ptr fs:[eax],esp
//The following assembly instruction is two byte in delphi, 4 byte in C, and They are entirely different
004D52D3 C6 45 FF 00          mov         byte ptr [ebp-1],0   
004D52D7 C6 05 18 54 4E 00 00 mov         byte ptr ds:[4E5418h],0
004D52DE C6 05 20 54 4E 00 00 mov         byte ptr ds:[4E5420h],0
004D52E5 C6 05 19 54 4E 00 00 mov         byte ptr ds:[4E5419h],0
004D52EC 33 C0                xor         eax,eax
004D52EE 55                   push        ebp
004D52EF 68 E5 54 4D 00       push        4D54E5h
004D52F4 64 FF 30             push        dword ptr fs:[eax]  
004B52F7 64 89 20             mov         dword ptr fs:[eax],esp
004B52FA 8A 45 08             mov         al,byte ptr [ebp+8]
004B52FD E8 FA FD FF FF       call        039B50FC  
004B5302 85 C0                test        eax,eax
004B5304 74 11                je          039B5317  

And noticable is use of fs segment register in delphi dll. Is delphi's PE model is flat?
Edit5: dumpbin /disasm produces an assembly listing exactly matching that of C disassembly, different from disassembly of Delphi.

解决方案

688ABA2900 0029B8ED 64FF30 push dword ptr fs:[eax] 0029B8F0 648920 mov fs:[eax], esp //The following assembly instruction is two byte in delphi, 4 byte in C, and they are entirely different 0029B8F3 33DB xor eax, eax //different from C disassembler 0029B8F5 C605F0FF290000 mov byte ptr


0029FFF0],


00 0029B8FC 33C0 xor eax, eax 0029B8FE 55 push ebp 0029B8FF 6863BA2C00 push


这篇关于如何将C字符串传递给dll中的pascal函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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