Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
延迟绑定调用C#方法,并从未更改的C+中输出参数+; 目标是这样的:从unAMangeC++调用.NET库的方法,使用不使用COM和导入TLB库的后期绑定。_C#_C++_Late Binding_Language Interoperability - Fatal编程技术网

延迟绑定调用C#方法,并从未更改的C+中输出参数+; 目标是这样的:从unAMangeC++调用.NET库的方法,使用不使用COM和导入TLB库的后期绑定。

延迟绑定调用C#方法,并从未更改的C+中输出参数+; 目标是这样的:从unAMangeC++调用.NET库的方法,使用不使用COM和导入TLB库的后期绑定。,c#,c++,late-binding,language-interoperability,C#,C++,Late Binding,Language Interoperability,我有一个用c#编写的普通类(只是为了测试),放在用Framework4.0编译的类库(CSLib)中 公共类MyCSObject { 字符串_str=“Test” 我已经创建了我在这里列出的普通cpp应用程序: #include "stdafx.h" #include <stdio.h> #include <windows.h> #include <metahost.h> #pragma comment(lib, "mscoree.lib") // Imp

我有一个用c#编写的普通类(只是为了测试),放在用Framework4.0编译的类库(CSLib)中

公共类MyCSObject { 字符串_str=“Test”

我已经创建了我在这里列出的普通cpp应用程序:

#include "stdafx.h"
#include <stdio.h>
#include <windows.h>

#include <metahost.h>
#pragma comment(lib, "mscoree.lib")

// Import mscorlib.tlb (Microsoft Common Language Runtime Class Library).
#import "mscorlib.tlb" raw_interfaces_only              \
 high_property_prefixes("_get","_put","_putref")        \
 rename("ReportEvent", "InteropServices_ReportEvent")
using namespace mscorlib;
#pragma endregion

int main()
{
HRESULT hr;

ICLRMetaHost *pMetaHost = NULL;
ICLRRuntimeInfo *pRuntimeInfo = NULL;

// ICorRuntimeHost and ICLRRuntimeHost are the two CLR hosting interfaces
// supported by CLR 4.0. Here we demo the ICorRuntimeHost interface that 
// was provided in .NET v1.x, and is compatible with all .NET Frameworks. 
ICorRuntimeHost *pCorRuntimeHost = NULL;

IUnknownPtr spAppDomainThunk = NULL;
_AppDomainPtr spDefaultAppDomain = NULL;

// The .NET assembly to load.
bstr_t bstrAssemblyName(L"CSLib");
_AssemblyPtr spAssembly = NULL;

// The .NET class to instantiate.
bstr_t bstrClassName(L"CSLib.MyCSObject" );
_TypePtr spType = NULL;
variant_t vtObject;
variant_t vtEmpty;

// The instance method in the .NET class to invoke.
bstr_t bstrMethodNameGet(L"GetString");
bstr_t bstrMethodNamePut(L"PutString");

bstr_t bstrparam(L"Helloworld");
variant_t vtRet;

SAFEARRAY *psaMethodArgs = NULL;
variant_t vtStringRet;

// 
// Load and start the .NET runtime.
// 

wprintf(L"Load and start the .NET runtime %s \n", L"v4.0.30319");

hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost));
hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo));

hr = pRuntimeInfo->GetInterface(CLSID_CorRuntimeHost,
    IID_PPV_ARGS(&pCorRuntimeHost));

hr = pCorRuntimeHost->Start();
// Get a pointer to the default AppDomain in the CLR.
hr = pCorRuntimeHost->GetDefaultDomain(&spAppDomainThunk);
hr = spAppDomainThunk->QueryInterface(IID_PPV_ARGS(&spDefaultAppDomain));


// Load the .NET assembly.
hr = spDefaultAppDomain->Load_2(bstrAssemblyName, &spAssembly);

// Get the Type of CSSimpleObject.
hr = spAssembly->GetType_2(bstrClassName, &spType);

// Instantiate the class.
hr = spAssembly->CreateInstance(bstrClassName, &vtObject);

// Call the instance method of the class.
//   public string ToString();

// Create a safe array to contain the arguments of the method.
psaMethodArgs = SafeArrayCreateVector(VT_VARIANT, 0, 1);
VARIANT vtpar;
vtpar.vt = VT_BSTR;
vtpar.bstrVal = bstrparam;
long r = 0;
hr = SafeArrayPutElement(psaMethodArgs, &r, &vtpar);

// Invoke the "ToString" method from the Type interface.
hr = spType->InvokeMember(bstrMethodNamePut, 
                        static_cast<BindingFlags>( BindingFlags_InvokeMethod | BindingFlags_Instance | BindingFlags_Public),
                        NULL, 
                        vtObject, 
                        psaMethodArgs, 
                        NULL, 
                        NULL, 
                        NULL,
                        &vtRet);


BSTR bstr(_T(""));
SAFEARRAY* psaMethodArgsByRef = SafeArrayCreateVector(VT_VARIANT , 0, 1);
VARIANT vtbstr;
vtbstr.vt = VT_BSTR | VT_BYREF;
vtbstr.pbstrVal = &bstr;
r = 0;
hr  = SafeArrayPutElement(psaMethodArgsByRef, 0, &vtbstr);

SAFEARRAY* modifiers = NULL;

// VARIANT WITH INSDE VARIANT_BOOL
/*modifiers = SafeArrayCreateVector(VT_VARIANT, 0, 1);
VARIANT vtmod;
vtmod.vt = VT_BOOL;
vtmod.boolVal = VARIANT_TRUE;
hr  = SafeArrayPutElement(psaMethodArgsByRef, 0, &vtmod);*/

// VARIANT_BOOL
/*modifiers = SafeArrayCreateVector(VT_BOOL, 0, 1);
VARIANT_BOOL bmod = VARIANT_TRUE;
hr = SafeArrayPutElement(psaMethodArgsByRef, 0, &bmod);*/





hr = spType->InvokeMember(bstrMethodNameGet,
    static_cast<BindingFlags>(BindingFlags_InvokeMethod | BindingFlags_Instance | BindingFlags_Public),
    NULL,
    vtObject,
    psaMethodArgsByRef,
    modifiers,
    NULL,
    NULL,
    &vtRet);



return 0;
}

特别是在SAFEARRAY modifiers参数中:我不知道如何设置此参数,我尝试了不同的解决方案(就像我在代码中注释的解决方案)当我从非托管C++调用这个方法时,没有找到任何文档。

这是以前被问及的,没有人会发布一个无用的答案。CLR遇到了麻烦,把调用转换成变量后调用,但只有当它有[OUT ]时才这样做。您的意思是,只有当.NET方法的参数标记为[out]时,调用方法的这种方式才有效吗参数?但是我也不能这样做…也许我传递修饰符参数时出错了?以前有人问过,没有人给出过没有帮助的答案。CLR在调用后将参数转换回变量时遇到了麻烦,但只有当它有[Out]时才会这样做属性。你的意思是,只有当.NET方法的参数被标记为[out]参数时,调用方法的这种方式才会起作用吗?但是我也无法这样做……也许我传递修饰符参数时出错了?
#include "stdafx.h"
#include <stdio.h>
#include <windows.h>

#include <metahost.h>
#pragma comment(lib, "mscoree.lib")

// Import mscorlib.tlb (Microsoft Common Language Runtime Class Library).
#import "mscorlib.tlb" raw_interfaces_only              \
 high_property_prefixes("_get","_put","_putref")        \
 rename("ReportEvent", "InteropServices_ReportEvent")
using namespace mscorlib;
#pragma endregion

int main()
{
HRESULT hr;

ICLRMetaHost *pMetaHost = NULL;
ICLRRuntimeInfo *pRuntimeInfo = NULL;

// ICorRuntimeHost and ICLRRuntimeHost are the two CLR hosting interfaces
// supported by CLR 4.0. Here we demo the ICorRuntimeHost interface that 
// was provided in .NET v1.x, and is compatible with all .NET Frameworks. 
ICorRuntimeHost *pCorRuntimeHost = NULL;

IUnknownPtr spAppDomainThunk = NULL;
_AppDomainPtr spDefaultAppDomain = NULL;

// The .NET assembly to load.
bstr_t bstrAssemblyName(L"CSLib");
_AssemblyPtr spAssembly = NULL;

// The .NET class to instantiate.
bstr_t bstrClassName(L"CSLib.MyCSObject" );
_TypePtr spType = NULL;
variant_t vtObject;
variant_t vtEmpty;

// The instance method in the .NET class to invoke.
bstr_t bstrMethodNameGet(L"GetString");
bstr_t bstrMethodNamePut(L"PutString");

bstr_t bstrparam(L"Helloworld");
variant_t vtRet;

SAFEARRAY *psaMethodArgs = NULL;
variant_t vtStringRet;

// 
// Load and start the .NET runtime.
// 

wprintf(L"Load and start the .NET runtime %s \n", L"v4.0.30319");

hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost));
hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo));

hr = pRuntimeInfo->GetInterface(CLSID_CorRuntimeHost,
    IID_PPV_ARGS(&pCorRuntimeHost));

hr = pCorRuntimeHost->Start();
// Get a pointer to the default AppDomain in the CLR.
hr = pCorRuntimeHost->GetDefaultDomain(&spAppDomainThunk);
hr = spAppDomainThunk->QueryInterface(IID_PPV_ARGS(&spDefaultAppDomain));


// Load the .NET assembly.
hr = spDefaultAppDomain->Load_2(bstrAssemblyName, &spAssembly);

// Get the Type of CSSimpleObject.
hr = spAssembly->GetType_2(bstrClassName, &spType);

// Instantiate the class.
hr = spAssembly->CreateInstance(bstrClassName, &vtObject);

// Call the instance method of the class.
//   public string ToString();

// Create a safe array to contain the arguments of the method.
psaMethodArgs = SafeArrayCreateVector(VT_VARIANT, 0, 1);
VARIANT vtpar;
vtpar.vt = VT_BSTR;
vtpar.bstrVal = bstrparam;
long r = 0;
hr = SafeArrayPutElement(psaMethodArgs, &r, &vtpar);

// Invoke the "ToString" method from the Type interface.
hr = spType->InvokeMember(bstrMethodNamePut, 
                        static_cast<BindingFlags>( BindingFlags_InvokeMethod | BindingFlags_Instance | BindingFlags_Public),
                        NULL, 
                        vtObject, 
                        psaMethodArgs, 
                        NULL, 
                        NULL, 
                        NULL,
                        &vtRet);


BSTR bstr(_T(""));
SAFEARRAY* psaMethodArgsByRef = SafeArrayCreateVector(VT_VARIANT , 0, 1);
VARIANT vtbstr;
vtbstr.vt = VT_BSTR | VT_BYREF;
vtbstr.pbstrVal = &bstr;
r = 0;
hr  = SafeArrayPutElement(psaMethodArgsByRef, 0, &vtbstr);

SAFEARRAY* modifiers = NULL;

// VARIANT WITH INSDE VARIANT_BOOL
/*modifiers = SafeArrayCreateVector(VT_VARIANT, 0, 1);
VARIANT vtmod;
vtmod.vt = VT_BOOL;
vtmod.boolVal = VARIANT_TRUE;
hr  = SafeArrayPutElement(psaMethodArgsByRef, 0, &vtmod);*/

// VARIANT_BOOL
/*modifiers = SafeArrayCreateVector(VT_BOOL, 0, 1);
VARIANT_BOOL bmod = VARIANT_TRUE;
hr = SafeArrayPutElement(psaMethodArgsByRef, 0, &bmod);*/





hr = spType->InvokeMember(bstrMethodNameGet,
    static_cast<BindingFlags>(BindingFlags_InvokeMethod | BindingFlags_Instance | BindingFlags_Public),
    NULL,
    vtObject,
    psaMethodArgsByRef,
    modifiers,
    NULL,
    NULL,
    &vtRet);



return 0;
}
virtual HRESULT __stdcall InvokeMember (
    /*[in]*/ BSTR name,
    /*[in]*/ enum BindingFlags invokeAttr,
    /*[in]*/ struct _Binder * Binder,
    /*[in]*/ VARIANT Target,
    /*[in]*/ SAFEARRAY * args,
    /*[in]*/ SAFEARRAY * modifiers,
    /*[in]*/ struct _CultureInfo * culture,
    /*[in]*/ SAFEARRAY * namedParameters,
    /*[out,retval]*/ VARIANT * pRetVal ) = 0;