使用 C++ 中的 C# DLL:使用字符串作为参数的函数的问题

Posted

技术标签:

【中文标题】使用 C++ 中的 C# DLL:使用字符串作为参数的函数的问题【英文标题】:using C# DLL from C++: problem with functions with strings as parameters 【发布时间】:2010-06-21 03:30:43 【问题描述】:

从这个例子开始:http://support.microsoft.com/kb/828736 我试图在我的 C# DLL 中添加一个测试函数,它将字符串作为参数。我的 C# DLL 代码如下:

namespace CSharpEmailSender

   // Interface declaration.
   public interface ICalculator
   
       int Add(int Number1, int Number2);
       int StringTest(string test1, string test2);
   ;

// Interface implementation.
public class ManagedClass : ICalculator

    public int Add(int Number1, int Number2)
    
        return Number1 + Number2;
    

    public int StringTest(string test1, string test2)
    
        if (test1 == "hello")
            return(1);

        if (test2 == "world")
            return(2);

        return(3);
    

然后我使用 regasm 注册这个 DLL。我在我的 C++ 应用程序中使用它,如下所示:

using namespace CSharpEmailSender;
using namespace std;

int _tmain(int argc, _TCHAR* argv[])

// Initialize COM.
HRESULT hr = CoInitialize(NULL);

// Create the interface pointer.
ICalculatorPtr pICalc(__uuidof(ManagedClass));

long lResult = 0;
long lResult2 = 0;

pICalc->Add(115, 110, &lResult);
wprintf(L"The result is %d", lResult);

pICalc->StringTest(L"hello", L"world", &lResult2);
wprintf(L"The result is %d", lResult2);

// Uninitialize COM.
CoUninitialize();

return 0;

运行后,lResult 是正确的(值为 225),但 lResult2 为零。知道我做错了什么吗?

【问题讨论】:

您是否尝试过调试程序并在StringTest 函数中设置断点?你能检查一下传入的字符串的值吗?如果是,它们是什么? 【参考方案1】:

在不尝试编译的情况下,互操作可能期望字符串为BSTR 类型。您可以尝试以下方法吗?

pICalc->StringTest(CComBSTR(L"hello"), CComBSTR(L"world"), &lResult2);

pICalc->StringTest(::SysAllocString(L"hello"), ::SysAllocString(L"world"), &lResult2); 

【讨论】:

我正在使用 Visual C++ Express 2008 - 似乎我需要获取平台 SDK 才能使用 CComBSTR :( 不需要,只是为了测试,做::SysAllocString(L"hello") 根据您的第二个建议,我收到此错误:无法将参数 1 从 'BSTR' 转换为 'SAFEARRAY *' 有趣,然后我没有建议了:( 不知道我是否尝试了一些更改并忘记重新充气,但它现在可以正常使用您的第二个建议!【参考方案2】:

您在StringTest 中使用== 进行字符串比较,它会进行引用比较。这(通常)在纯 C# 中有效,因为所有字符串都是 intern,但通过 COM 传递的字符串将 与它们在 C# 中的等效字符串引用相等。尝试改用Equals

【讨论】:

我不这么认为。看看这里:msdn.microsoft.com/en-us/library/system.string.op_equality.aspx - 这个操作符是使用 Equals 方法实现的,这意味着比较对象被测试为引用和值相等的组合。此运算符执行序数比较。

以上是关于使用 C++ 中的 C# DLL:使用字符串作为参数的函数的问题的主要内容,如果未能解决你的问题,请参考以下文章

如何将 C# 中的二维数组传递给 C++ DLL?

C#编组来自C++ DLL的无符号字符返回值[重复]

在 C# 中使用带有字符串的 C++ 类 (Dll)

性能提升:使用c#调用c++(核心代码优化)

使用 Dllimport 将一个非常大的字符串作为字节数组从 C++ 传递到 C#

在 C#(WPF) 中使用 C++ dll