C++ 托管 clr 调用库不在 safearray 参数中返回字符串

Posted

技术标签:

【中文标题】C++ 托管 clr 调用库不在 safearray 参数中返回字符串【英文标题】:C++ hosting clr invoke library don't return string in safearray parameter 【发布时间】:2014-09-28 16:54:07 【问题描述】:

我有这个 CSharp 库:

使用系统; 命名空间 MyNetLib 公共课 Myclass public int MyFunc(string strin, ref string strout) strout = "输入字符串为:" + strout; 返回字符串。长度;

我运行下面的代码,但在 SafeArray 参数中没有返回输出字符串。由于没有错误指示,出了什么问题?

#include #include #include #pragma 注释(lib,“mscoree.lib”) #import raw_interfaces_only high_property_prefixes ("_get", "_put", "_putref") 重命名 ("ReportEvent", "StdReportEvent") 重命名 ("_DSA", "_CLR_DSA") 使用命名空间 mscorlib; 无效的主要() ICorRuntimeHost *pCorRuntimeHost = NULL; HRESULT hr = CorBindToRuntimeEx(L"v4.0.30319", L"srv", STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN | STARTUP_CONCURRENT_GC, CLSID_CorRuntimeHost, IID_PPV_ARGS( &pCorRuntimeHost ) ); pCorRuntimeHost->Start(); IUnknown *pUnkDomain = NULL; _AppDomain *pAppDomain = NULL; hr = pCorRuntimeHost-> GetDefaultDomain ((IUnknown **) &pUnkDomain); hr = pUnkDomain-> QueryInterface (__uuidof (_AppDomain), (void **) &pAppDomain); _Assembly *pAssembly = NULL; BSTR bstrAssemblyString = SysAllocString (L"MyNetLib"); hr = pAppDomain-> Load_2 (bstrAssemblyString, &pAssembly); SysFreeString (bstrAssemblyString); _Type *pType = NULL; BSTR typeString = SysAllocString (L"MyNetLib.Myclass"); 变量对象; hr = pAssembly-> GetType_2 (typeString, &pType); hr = pAssembly-> CreateInstance (typeString, &obj); SysFreeString(类型字符串); 长索引 = 0; SAFEARRAY* safeArgs = NULL; SafeArrayAllocDescriptor(1, &safeArgs); safeArgs->cbElements = sizeof(VARIANT); safeArgs->rgsabound[0].lLbound = 0; safeArgs->rgsabound[0].cElements = 2; SafeArrayAllocData(safeArgs); 变体 arg1; VariantInit(&arg1); V_BSTR(&arg1) = SysAllocString(L"字符串输入。"); V_VT(&arg1) = VT_BSTR; 变体 arg2; BSTR pbstrOut = NULL; VariantInit(&arg2); V_BSTRREF(&arg2) = & pbstrOut; V_VT(&arg2) = VT_BSTR | VT_BYREF; 变体 retVal; SafeArrayPutElement(safeArgs, &index, &arg1); 索引++; SafeArrayPutElement(safeArgs, &index, &arg2); BSTR methodString = SysAllocString (L"MyFunc"); hr = pType-> InvokeMember_3 (methodString, (BindingFlags) (BindingFlags_InvokeMethod | BindingFlags_Public | BindingFlags_Instance), NULL, obj, safeArgs, &retVal);

【问题讨论】:

完全相同的问题is here。我不认为你可以让它工作,它根本不会在调用后将 object[] 元素编组回 SAFEARRAY 。它通常需要在参数上使用 [In, Out] 来说服编组器花时间将它们复制回来,这是缺失的。 解决方法是函数通过 IntPtr 返回字符串。 【参考方案1】:

你可以试试 StringBuilder 吗?把函数改成:

public int MyFunc(string strin, ref StringBuilder strout)
    
        strout.insert(0, strin);
        return strin.Length;
    

由于字符串对象在.NET中是只读的,如果你想改变字符串的内容,应该使用StringBuilder

【讨论】:

以上是关于C++ 托管 clr 调用库不在 safearray 参数中返回字符串的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ /CLR 项目中使用 C++ DLL 库项目

CLR 在调用 c++ 函数时如何避免重击?

运行使用 /clr 构建的 DLL 的本机 C++ 应用程序时访问冲突

如何重新导出 CLR c++ 静态库

将静态本机库链接到托管 C++ 项目会在

创建强命名托管 (/clr) C++ 程序集