Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Delphi动态链接库的使用及若干问题_C#_Delphi_Dll_Pinvoke - Fatal编程技术网

C# Delphi动态链接库的使用及若干问题

C# Delphi动态链接库的使用及若干问题,c#,delphi,dll,pinvoke,C#,Delphi,Dll,Pinvoke,我想使用Delphi制作的dll。它具有以下功能: 函数CryptStr(str,Key:AnsiString;DecryptStr:boolean):AnsiString;stdcall 我在/bin/debug和应用程序根目录中复制了Dll。我的代码是: [DllImport("Crypt2.dll", EntryPoint = "CryptStr", CallingConvention = CallingConvention.StdCall)] static extern

我想使用Delphi制作的dll。它具有以下功能: 函数CryptStr(str,Key:AnsiString;DecryptStr:boolean):AnsiString;stdcall

我在/bin/debug和应用程序根目录中复制了Dll。我的代码是:

 [DllImport("Crypt2.dll", EntryPoint = "CryptStr", CallingConvention = CallingConvention.StdCall)]
        static extern string CryptStr( string str,  string Key, bool DecryptStr);
        public string g = "";
        private void Form1_Load(object sender, EventArgs e)
        {
          g=CryptStr("999", "999999", true);
          MessageBox.Show(g);
        }
我有一些问题: 1.即使我从这些路径中删除Dll,应用程序也不会引发未找到异常 2.当应用程序在g=CryptStr中运行时(“999”、“9999999”,true);它完成执行并显示表单,而不运行Messagebox行。
我尝试使用Marshal,但上面的错误仍然存在。

您不能期望从Delphi以外的编程环境调用该函数。这是因为它使用了对互操作无效的Delphi本机字符串。即使从Delphi调用,也需要使用与编译DLL时使用的Delphi版本相同的Delphi,以及
ShareMem
单元,以便共享内存管理器。对于两个Delphi模块之间的互操作,该函数甚至没有得到很好的设计

您需要更改DLL函数的签名。例如,您可以使用:

procedure CryptStr(
    str: PAnsiChar;
    Key: PAnsiChar;
    DecryptStr: boolean;
    output: PAnsiChar;
); stdcall;
在C#中,您可以这样声明:

[DllImport("Crypt2.dll")]
static extern void CryptStr(
    string str,
    string Key,
    bool DecryptStr,
    StringBuilder output
);
此更改要求调用方分配传递给函数的缓冲区。如果要查找这样做的示例,请搜索调用Win32 API的示例
GetWindowText

如果您使用的是UTF-16文本而不是8位ANSI,则可以使用在共享COM堆上分配的COM
BSTR
,但我怀疑该选项对您不可用

至于您的程序没有显示任何错误,我建议您参考以下帖子:


表单接受加载事件中的任何异常。在这种情况下,你需要自己处理。因此,添加一个合适的try..catch。我认为他也可以使用BSTR/WideString,甚至OLE TStrings适配器进行互操作。我猜C#支持BSTR DLL API?@Arioch'The
[Marshallas(UnmanagedType.BSTR)]
,但问题是
BSTR
是UTF-16,而原始代码是ANSI。因此,这是一个编码问题,而不是编组的可能性。通过将声明更改为使用
WideString
可以自动进行转换。PS:我只是对标记终止字符串在一般情况下的用法有一个偏见:-)@Arioch'The要保持相同的行为,您必须将8位与Delphi代码之间的转换移动到Delphi代码中,而不是由封送员完成。@Arioch'The Well,只要将两个输入字符串分配给函数顶部的
AnsiString
变量。FWIW,看看我对这个奇怪的相似问题的回答的评论:那么,谁知道这个DLL到底是什么!!