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++ 程序集