【问题标题】:C# DLL Calling SOAP Web Service From C++ AppC# DLL 从 C++ 应用程序调用 SOAP Web 服务
【发布时间】:2020-02-05 23:54:09
【问题描述】:

根据网上的大量文章,我创建了一个简单的 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.dllCSDLL.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 响应的调用抛出异常并显示以下消息:

异常消息: Message = "向https://server-address:port/path 发出 HTTP 请求时发生错误。这可能是由于在 HTTPS 情况下未使用 HTTP.SYS 正确配置服务器证书。这也可能是由于客户端和服务器之间的安全绑定。 内部异常消息: Message = "身份验证失败,因为远程方已关闭传输流。"

如果从 C++ 控制台应用程序调用 DLL 而不是从 C# 控制台应用程序调用同一个 DLL,为什么会出现此问题?我猜它必须与安全性有关,因为如果调用简单的数学 Add 方法,两者都会执行得很好,但是如果调用执行 SOAP 请求的方法,C# 控制台应用程序将执行得很好,而 C++ 控制台应用程序将导致 DLL抛出异常?

【问题讨论】:

    标签: c# c++ soap dll http.sys


    【解决方案1】:

    经过大量阅读,事实证明这是因为 SecurityProtocol 被设置为不同的 SecurityProtocolType 如果从 C# 与 C++ 应用程序调用 C# DLL。

    为了解决这个问题,我必须在发出任何请求之前像下面这样设置SecurityProtocol

    if (ServicePointManager.SecurityProtocol == (SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls))
    {
        // This was crucial to do to make web service call work when C# DLL is called 
        // from a C++ app.  It turns out that if webservice call is made:
        //   1) from C# console app calling C# DLL that makes web service call, 
        //      the SecurityProtocol is set to TLS | TLS11 | TLS12 | TLS13
        //   2) from C++ console app calling C# DLL that makes web service call,
        //      the SecurityProtocol is set to SSL3 | TLS
        // In case of 2) above, the call would throw exception as explained above
        // whereas 1) would work just fine.
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls 
           | SecurityProtocolType.Tls11 
           | SecurityProtocolType.Tls12; 
           // TLS13 was not available for some reason, so did not set it here
    }
    

    【讨论】:

    • 这拯救了我的一天!对于那些会看到该帖子的人来说,此代码必须放在 创建网络请求之前,这听起来很明显,但最好告诉它。如果你想启用 TLS 1.3,你可以使用这个小技巧:ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls |安全协议类型.Tls11 |安全协议类型.Tls12; | (安全协议类型)12288; // Tls13;
    猜你喜欢
    • 2013-11-19
    • 1970-01-01
    • 1970-01-01
    • 2012-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-29
    • 2015-03-19
    相关资源
    最近更新 更多