2012-09-16 9 views
9
में रेफरी पैरामीटर मार्शल करने के लिए है

यहाँ मेरी सी # सर्वर विधि है:यह संभव SAFEARRAY

public void Exec(out int status, string output) 
{ 
    status = 3; 
    Console.WriteLine("Exec({0}, ...)", status); 

    output = string.Format("Hello from .NET {0}", DateTime.Now); 
    Console.WriteLine("Exec(..., {0})", output);   
} 

मेरे सी ++ ग्राहक की स्थापना और इस विधि बुला रहा है। यह ठीक काम करता है, लेकिन स्थिति और आउटपुट वैरिएबल चेनिंग प्रतीत नहीं होता है। ऐसा लगता है कि वे संदर्भ के बजाय मूल्य से गुजर रहे हैं।

यहाँ मेरे मुवक्किल कोड है:

InitCLR(); 

LONG index = 0; 

LONG i1 = 12; // just some number for testing 
BSTR s1 = SysAllocString(L"Hello world"); 

SAFEARRAY* args = NULL; 
CHECK_HRESULT(SafeArrayAllocDescriptor(1, &args)); 

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

CHECK_HRESULT(SafeArrayAllocData(args)); 

// byref not working for in/out param 
VARIANT arg1; 
VariantInit(&arg1); 
V_I4REF(&arg1) = &i1; 
V_VT(&arg1) = VT_I4 | VT_BYREF; 

// byref not working 
VARIANT arg2; 
VariantInit(&arg2); 
V_BSTR(&arg2) = SysAllocString(L"Hello world"); 
V_VT(&arg2) = VT_BSTR; 

index = 0; 
CHECK_HRESULT(SafeArrayPutElement(args, &index, &arg1)); 

index = 1; 
CHECK_HRESULT(SafeArrayPutElement(args, &index, &arg2)); 

int bindingFlags = mscorlib::BindingFlags_InvokeMethod | 
    mscorlib::BindingFlags_Instance | 
    mscorlib::BindingFlags_Public; 

VARIANT retval; 
VariantInit(&retval); 

bstr_t methodName("Exec"); 
HRESULT hRes = Type->InvokeMember_3(
    methodName, 
    static_cast<mscorlib::BindingFlags>(bindingFlags), 
    NULL, // binder * 
    Instance, 
    args, 
    &retval); 

_tprintf(TEXT("Exec() == 0x%x\n"), hRes); 

_tprintf(TEXT("i1=%d\n"), i1); 

किसी SAFEARRAY तर्क इतना है कि 'रेफरी' पैरामीटर वापस बाहर कॉपी कर रहे हैं स्थापित करने पर सहायता प्रदान कर सकते हैं?

+0

क्या आप इस जटिल समाधान के लिए जाने का कोई कारण हैं? क्या आप अपने सी ++ ऐप को/clr स्विच के साथ संकलित नहीं कर सकते हैं और संकलक को इसके बारे में चिंता करने दें? मैं बहुत सारे इंटरऑप सामान कर रहा हूं, लेकिन मुझे मैन्युअल तर्कों को मैन्युअल रूप से कभी नहीं करना पड़ा। – PMF

उत्तर

0

मैं पूरा जवाब पता हो सकता है, लेकिन मैं अपने कोड में दो बातें स्थान:

स्ट्रिंग सही ढंग से संदर्भ द्वारा पारित नहीं किया गया है सी # में

स्ट्रिंग्स अपरिवर्तनीय संदर्भ वस्तुओं रहे हैं। इसका मतलब है कि उनके संदर्भ संदर्भित होते हैं (मूल्य के अनुसार), और स्ट्रिंग बनने के बाद, आप इसे संशोधित नहीं कर सकते हैं। यदि आप स्ट्रिंग मान संशोधित करते हैं, तो आप वास्तव में एक नई स्ट्रिंग बनाते हैं और इसके लिए स्थानीय संदर्भ बदलते हैं।

public void Exec(out int status, out string output) 
{ 
    ... 
} 

आप रेफरी के बजाय बाहर

का उपयोग करना चाहिए:

के बारे में यह here

तो, आप कुछ इस तरह करने के लिए अपने सी # समारोह की परिभाषा बदलने की जरूरत है एक महान स्पष्टीकरण नहीं है

आप सी # फ़ंक्शन कॉल से पहले तर्क मानों को शुरू करने के लिए तर्क मान प्रारंभ नहीं करते हैं।

तो, आपको कीवर्ड के बजाय रेफरी का उपयोग करना चाहिए;

public void Exec(ref int status, ref string output) 
{ 
    ... 
} 
संबंधित मुद्दे