将字符串从Delphi传递到C#将返回null。但是,当我从Delphi调用Delphi库时,它工作得很好。如何从Delphi接收字符串
我是Delphi的新手,一直在尝试为.NET制作一些DLL 我想要实现的是从DLL发送和接收txt输出 以下是我迄今为止所做的工作: Delphi库函数:将字符串从Delphi传递到C#将返回null。但是,当我从Delphi调用Delphi库时,它工作得很好。如何从Delphi接收字符串,c#,string,delphi,pchar,delphi.net,C#,String,Delphi,Pchar,Delphi.net,我是Delphi的新手,一直在尝试为.NET制作一些DLL 我想要实现的是从DLL发送和接收txt输出 以下是我迄今为止所做的工作: Delphi库函数: 函数DBConnet(inputStr:PChar;connStr:PChar):PAnsiChar;stdcall;出口; 变量 构造:字符串; s:字符串; 开始 inputStr:=PChar('Hello from Delphi!你好'+inputStr+connStr); 尝试 结果:=PAnsiChar(inputStr); 除了
函数DBConnet(inputStr:PChar;connStr:PChar):PAnsiChar;stdcall;出口;
变量
构造:字符串;
s:字符串;
开始
inputStr:=PChar('Hello from Delphi!你好'+inputStr+connStr);
尝试
结果:=PAnsiChar(inputStr);
除了
关于e:Exception-do
开始
结果:='异常';
结束;
结束;
结束;
出口
DBConnet;
结束。
以下是我在Delphi中的调用函数:
function DBConnet(inputStr: PChar; connStr: PChar): PChar; stdcall; external 'NewLib.dll';
procedure TUseDLLForm.functionxClick(Sender: TObject);
var
a: string;
conStr: string;
i: integer;
begin
a := 'firstname';
conStr := 'lastname';
ShowMessage(DBConnet(pchar(a), pchar(conStr)));
end;
这在Delphi到Delphi之间运行良好。但是当我试图从C#调用它时,收到的输出是空的
这是我的C代码块:
[DllImport(“NewLib.dll”,
CallingConvention=CallingConvention.StdCall,
CharSet=CharSet.Unicode)]
公共静态外部void DBConnet(字符串inputString,字符串
connectionString[Marshallas(UnmanagedType.BStr)]输出字符串dbStrObj);
然后大体上我这样称呼它:
DBConnet(inputString, connectionString, out dbStrObj);
您显示的DLL代码与您的C#代码不兼容 您的C#代码依赖于您的DLL不符合 默认情况下,
string
作为PWideChar
指针传递给DLL(如果您使用的是Delphi 2009+,PChar
映射到PWideChar
,否则它映射到PAnsiChar
)
此外,您的DLL函数正在返回一个PAnsiChar
,但是封送处理程序在默认情况下需要一个PWideChar
,因为您没有在C#端的DLL函数声明上应用[return:marshallas(UnmanagedType.LPStr)]
属性
但更重要的是,当DLL返回指向封送拆收器随后拥有的内存的指针时,必须使用CoTaskMemAlloc()
或等效项分配内存,因为封送拆收器默认使用CoTaskMemFree()
释放内存(请参阅)
您正在返回一个指向动态分配内存的指针,但是该内存没有使用CoTaskMemAlloc()
进行分配。事实上,内存实际上是由Delphi编译器管理的,当函数退出时会自动释放内存。因此,您实际上返回了一个指向C#的无效指针
事实上,您甚至没有返回指向C的指针!在C#端,您已声明DLL具有out
参数,但DLL端没有此类参数
尽管如此,还是尝试一下类似的方法:
动态链接库:
//如果不使用D2009+,请取消对此的注释。。。
{
类型
UnicodeString=宽字符串;
}
函数UnicodeStringToCoTaskMemStr(const s:UnicodeString):PWideChar;
变量
大小:整数;
开始
尺寸:=(长度)+1)*尺寸(宽字符);
结果:=PWideChar(CoTaskMemAlloc(大小));
如果结果为零,则
移动(PWideChar^,结果^,大小);
结束;
函数DBConnet(inputsr:PWideChar;connStr:PWideChar):PWideChar;stdcall;出口;
变量
sInput:单向破坏;
斯科恩:独角兽毁灭;
开始
尝试
sInput:=inputStr;
sConn:=connStr;
结果:=unicodestingtocotaskmemstr('Hello from Delphi!你好'+sInput+sConn);
除了
结果:=UnicodeStringToCoTaskMemStr('exception');
结束;
结束;
Delphi应用程序:
函数DBConnet(inputStr:PWideChar;connStr:PWideChar):PWideChar;stdcall;外部“NewLib.dll”;
//如果不使用D2009+,请取消对此的注释。。。
{
类型
UnicodeString=宽字符串;
}
过程TUseDLLForm.functionxClick(发送方:TObject);
变量
a:破坏;
施工:单体破坏;
ret:PWideChar;
开始
a:=“名字”;
conStr:=“lastname”;
ret:=DBConnet(PWideChar(a),PWideChar(const));
如果ret为零,则
开始
尝试
ShowMessage(ret);
最后
CoTaskMemFree(ret);
结束;
结束其他
ShowMessage('nil');
结束;
C#:
[DllImport(“NewLib.dll”,
CallingConvention=CallingConvention.StdCall,
CharSet=CharSet.Unicode)]
[返回:Marshallas(UnmanagedType.LPWStr)]
公共静态外部字符串DBConnet(string inputString、string connectionString);
或者,改用out
参数:
动态链接库:
//如果不使用D2009+,请取消对此的注释。。。
{
类型
UnicodeString=宽字符串;
}
函数UnicodeStringToCoTaskMemStr(const s:UnicodeString):PWideChar;
变量
大小:整数;
开始
尺寸:=(长度)+1)*尺寸(宽字符);
结果:=PWideChar(CoTaskMemAlloc(大小));
如果结果为零,则
移动(PWideChar^,结果^,大小);
结束;
函数DBConnet(inputStr:PWideChar;connStr:PWideChar;out-outputStr:PWideChar):布尔;stdcall;出口;
变量
sInput:单向破坏;
斯科恩:独角兽毁灭;
开始
结果:=假;
尝试
sInput:=inputStr;
sConn:=connStr;
outputStr:=UnicodeStringToCoTaskMemStr('Hello from Delphi!你好'+sInput+sConn);
结果:=outputStr nil;
除了
结束;
结束;
Delphi应用程序:
函数DBConnet(inputStr:PWideChar;connStr:PWideChar,out outputStr:PWideChar):布尔;stdcall;外部“NewLib.dll”;
//如果不使用D2009+,请取消对此的注释。。。
{
类型
UnicodeString=宽字符串;
}
过程TUseDLLForm.functionxClick(发送方:TObject);
变量
a:破坏;
施工:单体破坏;
ret:PWideChar;
开始
a:=“名字”;
conStr:=“lastname”;
如果DBConnet(PWideChar(a)、PWideChar(const)、ret)那么
开始
尝试
ShowMessage(ret);
最后
CoTaskMemFree(ret);
结束;
结束其他
ShowMessage('fail');
结束;
C#:
[DllImport(“NewLib.dll”,
CallingConvention=CallingConvention.StdCall,
CharSet=CharSet.Unicode)]
[返回:Marshallas(UnmanagedType.I1)]
公共静态外部bool DBConnet(字符串输入)