是否有可能在名帅SAFEARRAY ref参数 [英] Is it possible to marshal ref parameters in SAFEARRAY

查看:140
本文介绍了是否有可能在名帅SAFEARRAY ref参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是我的C#服务器方法:

Here is my C# server method:

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);         
}

我的C ++客户端设置和调用此方法。这工作得很好,但是状态和输出变量不会出现被链接。就好像他们正在按值传递,而不是通过引用。

My C++ client is setting up and calling this method. This works fine, but the status and output variables don't appear to be chaining. It's as though they're being passed by value instead of by reference.

下面是我的客户code:

Here's my client code:

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参数,使'裁判'PARAMS复制回了援助?

Can someone provide assistance on setting up the SAFEARRAY arguments so that the 'ref' params are copied back out?

推荐答案

我可能不知道完整的答案,但我发现两件事情在你的code:

I might not know the full answer, but I spot two things in your code:

字符串没有被正确引用传递

在C#中字符串是不可变的参考对象。这意味着,对它们的引用被传来传去(按价值计算),而一旦被创建一个字符串,则不能进行修改。如果修改字符串值,您实际创建一个新的字符串,并更改本地引用它。

Strings in C# are immutable reference objects. This means that references to them are passed around (by value), and once a string is created, you cannot modify it. If you modify string value, you actually create a new string and change local reference to it.

有一个关于它很好的解释这里

There is a great explanation about it here

所以,你需要在你的C#函数的定义修改为这样的事情:

So, you need to change the definition of your C# function to something like this:

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

您应该使用,而不是OUT REF

您似乎初始化参数值 C#函数调用之前不进的功能本身。

You seem to initialize argument values before C# function call not into function itself.

所以,你应该用裁判来代替了关键字;

So, you should use ref instead of out keyword;

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

这篇关于是否有可能在名帅SAFEARRAY ref参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆