2016-02-27 21 views
0

我想从我的C++程序内存缓冲区中加载并执行一个dotnet可执行文件。从C++调用dotnet程序集方法返回错误COR_E_SAFEARRAYTYPEMISMATCH

为了做到这一点,我试图调用一个dotnet程序集的主函数,我已经加载了我的C++项目。

首先我加载CRL运行时,得到加载好。

然后我从内存缓冲区加载dotnet.exe,它会被加载好。

然后我想通过调用它的Main函数来启动它。

此时,Invoke_3函数返回COR_E_SAFEARRAYTYPEMISMATCH。 我不明白为什么,因为我使用GetParameters函数检索参数,该函数填充SAFEARRAY以传递给Invoke函数。 有人知道这个参数有什么问题吗? 提前谢谢!

// Up here we correctly load the CRL runtime 

// Load up our dotnet file inside a std::string 
string sFileData = FileToString("C:\\dotnet.exe"); 

// Copy our file data inside a SAFEARRAY 
SAFEARRAYBOUND bounds = { sFileData.size(), 0 }; 
SAFEARRAY *pSA = SafeArrayCreate(VT_UI1, 1, &bounds); 
void* data; 
HRESULT hr = SafeArrayAccessData(pSA, &data); 
CopyMemory(data, sFileData.c_str(), sFileData.size()); 
hr = SafeArrayUnaccessData(pSA); 

if (pSA) 
{ 
    // Load our managed assembly: 
    _AssemblyPtr spAssembly = nullptr; 
    hr = spAppDomain->Load_3(pSA, &spAssembly); 

    // Get the entrypoint of the assembly, which should be the "Main" function 
    _MethodInfoPtr entryp; 
    hr = spAssembly->get_EntryPoint(&entryp); 

    // Get the parameters of the entrypoint function and save them in a SAFEARRAY 
    SAFEARRAY *pArrParams; 
    hr = entryp->GetParameters(&pArrParams); 

    // Call the entrypoint passing parameters in the SAFEARRAY. 
    // Returns error COR_E_SAFEARRAYTYPEMISMATCH 
    VARIANT retval; 
    hr = entryp->Invoke_3(_variant_t(), pArrParams, &retval); 
} 
+1

Main()方法通常具有字符串[]参数。你不传递一个字符串数组,传递ParameterInfo []当然注定会失败。你需要一个安全的BSTR阵列。 –

+0

但是,不应该entryp-> GetParameters(&pArrParams)函数自动填充SAFEARRAY与我们稍后将调用的entryp方法的正确参数? 如果dotnet Main函数有不同的参数呢? 谢谢 – Flavio

+1

它告诉你有关参数的*类型*。如果它不是string [],那么你应该抱怨。好吧,你不需要帮助,因为你发现了。传递参数的*值*取决于你。 –

回答

0

按照framework source for SafeArrayTypeMismatchException(它映射到COR_E_SAFEARRAYTYPEMISMATCH):

时的阵列的运行时类型比在元数据中指定的安全数组子类型不同抛出此异常。

因此,我敢肯定,这就是问题所在:

SafeArrayCreate(VT_UI1, 1, &bounds); 

VT_UI1是1个字节的无符号整数。但C#应用程序中的标准Main()方法需要一个4字节有符号整数数组。这些是不同的类型,因此是错误的。因此,您需要将代码更改为:

SafeArrayCreate(VT_I4, 1, &bounds); 
+0

但是,感谢您的回复,该函数未用于Invoke函数。该数组用于 'hr = spAppDomain-> Load_3(pSA,&spAssembly);'函数,它加载程序集很好。 返回错误的Invoke_3函数改为使用由entryp-> GetParameters(&pArrParams)填充的SAFEARRAY; 无论如何,我试图改变它,看看是否有一些差异,但如果我使用VT_I4 Load_3函数将失败。 – Flavio