根据网上的大量文章,我创建了一个简单的 C# DLL 类库,其中只有一个名为 Add 的方法。它接受 2 个整数并返回一个整数,如下所示。我还去了项目属性>构建>并选择了“注册COM互操作”选项:
namespace CSDLL
{
[ComVisible(true)]
public interface IMyClass
{
int Add(int x, int y);
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class MyClass : IMyClass
{
public int Add(int x, int y)
{
return x + y;
}
}
}
我成功构建了它(作为管理员),它生成了CSDLL.dll
文件CSDLL.tlb
。
接下来我创建了一个简单的 C++ 控制台应用程序,如下所示:
#include "stdafx.h"
#include <Windows.h>
#import "C:\path\to\my\CSDLL.tlb" no_namespace
int main()
{
CoInitialize(NULL);
IMyClassPtr obj;
obj.CreateInstance(__uuidof(MyClass));
printf("Add result = %d\n", obj->Add(2, 5));
CoUninitialize();
getchar();
return 0;
}
如果我运行它,我会在控制台窗口上打印出预期的结果。所以,这一切都很好。
接下来我修改了我的Add
方法,以便它调用一个 SOAP 端点,而不是添加 2 个整数。我将代码包装在 try...catch 中,如果 SOAP 按预期执行,则返回 1,如果未返回预期结果,则返回 0,然后从 catch 块中返回 2,这意味着存在如下异常:
public int Add()
{
try
{
BasicHttpsBinding binding = new BasicHttpsBinding();
binding.Security.Mode = BasicHttpsSecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
binding.UseDefaultWebProxy = false;
EndpointAddress address = new EndpointAddress(myEndPointString);
// create service myService by passing it binding and endpoint address
// pass necessary parameters to the service
// set ClientCredentials for my service
// get response from the service
MyServiceResponse resp = myService.DoSomething();
if (resp.acknowledged)
{
return 1;
}
else
{
return 0;
}
}
catch (Exception ex)
{
// just return 2 in case of an exception
return 2;
}
}
如果我从 C++ 控制台应用程序调用这个修改后的 DLL,它总是返回 2 = 表示我的上面的代码抛出了一些异常。我在 .NET Framework 4.8 上。
但是,如果我从通过添加对上面的 C# DLL 的引用创建的 C# 控制台应用程序调用它,则调用Add
返回 1 = 表示它成功执行,结果我希望从中获得。
因此,相同的 C# DLL 返回 2 个不同的结果,具体取决于它是从 C++ 还是 C# 控制台应用程序调用的。
在设置了一些断点并调试了我的 DLL 之后,我发现对DoSomething
响应的调用抛出异常并显示以下消息:
异常消息:消息 =“向https://server-address:port/path发出 HTTP 请求时发生错误。这可能是由于在 HTTPS 情况下未使用 HTTP.SYS 正确配置服务器证书. 这也可能是由于客户端和服务器之间的安全绑定不匹配造成的。内部异常消息:Message = "身份验证失败,因为远程方已关闭传输流。"
如果从 C++ 控制台应用程序调用 DLL 而不是从 C# 控制台应用程序调用相同的 DLL,为什么会出现此问题?我猜它必须与安全性有关,因为如果调用简单的数学Add
方法,两者都会执行得很好,但是如果调用执行 SOAP 请求的方法,C# 控制台应用程序将执行得很好,而 C++ 控制台应用程序会导致 DLL 抛出异常?