lsalamon
lsalamon

Reputation: 8174

C++ hosting clr invoke library don't return string in safearray parameter

I have this CSharp library:

using System;
namespace MyNetLib
{
    public class Myclass
    {
        public int MyFunc(string strin, ref string strout)
        {
            strout = "Input string is: " + strout;
            return strin.Length;
        }
    }
}

I run the code below but no return of the output string in SafeArray parameter. What is wrong since there is no indication of error?

#include <atlbase.h>

#include <mscoree.h> 
#include <metahost.h>

#pragma comment (lib, "mscoree.lib") 

#import <mscorlib.tlb> raw_interfaces_only high_property_prefixes ("_get", "_put", "_putref") rename ("ReportEvent", "StdReportEvent") rename ("_DSA", "_CLR_DSA") 

using namespace mscorlib; 


void main()
{
    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"); 
    VARIANT obj; 
    hr = pAssembly-> GetType_2 (typeString, &pType); 
    hr = pAssembly-> CreateInstance (typeString, &obj); 
    SysFreeString (typeString); 

    LONG index = 0;
    SAFEARRAY* safeArgs = NULL;
    SafeArrayAllocDescriptor(1, &safeArgs);

    safeArgs->cbElements = sizeof(VARIANT);
    safeArgs->rgsabound[0].lLbound = 0;
    safeArgs->rgsabound[0].cElements = 2;

    SafeArrayAllocData(safeArgs);

    VARIANT arg1;
    VariantInit(&arg1);
    V_BSTR(&arg1) = SysAllocString (L"String input.");
    V_VT(&arg1) = VT_BSTR;

    VARIANT arg2;
    BSTR pbstrOut = NULL;
    VariantInit(&arg2);  
    V_BSTRREF(&arg2) = & pbstrOut;
    V_VT(&arg2) = VT_BSTR | VT_BYREF;

    VARIANT retVal; 

    SafeArrayPutElement(safeArgs, &index, &arg1);
    index++;
    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); 
}

Upvotes: 0

Views: 391

Answers (1)

Matt
Matt

Reputation: 6050

Can you try with StringBuilder? Change the function as:

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

As string object is readonly in .NET, StringBuilder should be used if you want to change the content of the string

Upvotes: 0

Related Questions