解决方案 »
- 数据过滤
- 请问delphix下双缓冲是自动开启的吗?
- Delphi2006 全 4CD 2.53GBT 下载
- 从本地读取bmp图片文件通过BDE存储到oracle数据库中?在线等。
- DBGridEh1里某行的“应收余额”=上一行的“应收余额”+本行的“应收增加”-本行的“应收减少”,“应收余额”怎么得到?
- 怎么一次删除dbgrid中的多行数据?
- 高手救我啊。Sql server 中出现Ole error
- 请问:如何在一个程序中单击其它程序中ToolBar上的ToolBotton按钮?
- bde连SQLSERVER,利用数据库用户为软件登陆用户?
- 修改注册表的问题
- Delphi控件遮挡问题
- ESC/POS 指令打印图片
在XE2写到DLL在Delphi2010调用,一直出错。最后没办法只能装个2010编译我写到DLL,就可以了。
Delphi在处理版本之间的转换很不到位
最好改成AnsiString
换成
str1,str2:AnsiString试试
或者
retMsg:=PAnsiChar( AnsiString( str1+'-'+str2) );
应该是D7的申明里漏了var
str1,str2:AnsiString;
或者
retMsg:=PAnsiChar( AnsiString( str1+'-'+str2) );
可以,完全正确。如果想要DelphiXE3写的DLL,用C++也可以调用,那么字符串的参数类型应该怎么定义?
PAnsiChar类型可以吗?还是必须用Pchar ??
2 D7的Pchar是PAnsiChar XE后是PWidechar。
不多说了
Library TestDll;Uses
System.SysUtils,
System.Classes;Function Test(Instr1, Instr2: PAnsiChar; Var retMsg: PAnsiChar): Integer; Stdcall;
Var
str1, str2: String;
Begin
str1 := String(Instr1);
str2 := String(Instr2);
//retMsg := PAnsiChar(ansiString(str1 + '-' + str2));
StrCopy(retMsg, PAnsiChar(ansiString(str1 + '-' + str2)));
Result := 1;
End;Exports
Test;End.Type
TTest = Function(Instr1, Instr2: PAnsiChar; Var retMsg: PAnsiChar): Integer; Stdcall;
Var
lhandle: THandle;
ltest: TTest;
retMsg: PAnsiChar;
Begin
lhandle := LoadLibrary('TestDll.dll');
If lhandle > 32 Then
Begin
@ltest := GetProcAddress(lhandle, 'Test');
GetMem(retMsg, 256);
If ltest(PChar(Edit1.Text), PChar(Edit2.Text), retMsg) = 1 Then
Begin
ShowMessage('调用成功,返回Msg:' + retMsg);
End;
FreeMem(retMsg);
End;Type
TTest = Function(Instr1, Instr2: PAnsiChar; Var retMsg: PAnsiChar): Integer; Stdcall;
Var
lhandle: THandle;
ltest: TTest;
retMsg: PAnsiChar;
Begin
lhandle := LoadLibrary('TestDll.dll');
If lhandle > 32 Then
Begin
@ltest := GetProcAddress(lhandle, 'Test');
GetMem(retMsg, 256);
If ltest(PAnsiChar(Ansistring(Edit1.Text)), PAnsiChar(Ansistring(Edit2.Text)), retMsg) = 1 Then
Begin
ShowMessage('调用成功,返回Msg:' + retMsg);
End;
FreeMem(retMsg);
End;
Char,在xe2中占2个字节,在D7占1个字节
随便,可以不用改,PAnsiChar就对应C++里的char*
1. 函数的签名不同,导出的是 var retMsg: PAnsiChar; 使用的却是 regMsg:Pansichar;后者无法接收到返回的值。
2. 导出函数使用UnicodeString(xe3string是UnicodeString),却硬生生的把他强制转换为PAnsiChar;
3. 函数返回的retMsg是由临时的函数内变量,函数结束,该变量消失。你获得的将是一个非法内存地址。
4. 对string的编译器自动引用计数管理认识不清,string的引用计数不能跨dll的,他是delphi特有的东西。解决方法
1. 签名一致用 var PansiChar
2. 函数用GetMem分配内存,并使用Ansistring封装数据,然后复制到分配的内存中
3. 返回分配的内存地址 调用的函数负责释放内存。因此dll还需提供一个释放内存的导出函数(将Freemem封装成导出函数);
str1+''+str2的内容是保存在临时变量中的,这个临时变量是局部变量,离开函数的时候就被回收了.
你转成PAnsiChar的地址指向的是无效的地址,之所以有时候会是正常的是因为内存管理器没有重用这块内存的话看上去像是对的.