C# C++;隐函数调用

C# C++;隐函数调用,c#,c++-cli,marshalling,C#,C++ Cli,Marshalling,所以我试图调用一个函数,它是OCX对象周围的一个被管理的包装器。有很大的困难。功能是 foo(System::Object ^% theBuffer) 其中'theBuffer'是字节数组。“foo”包装的非托管OCX的模板为 goo(VARIANT* theBuffer); 所以我试过了 System::Int32 buf[10]; foo(buf); 它失败了。及 Bitmap ^b; foo(b); 它可以编译,但显然调用的函数不会为我创建.NET位图 所以我想问题是,我该如何传递

所以我试图调用一个函数,它是OCX对象周围的一个被管理的包装器。有很大的困难。功能是

foo(System::Object ^% theBuffer)
其中'theBuffer'是字节数组。“foo”包装的非托管OCX的模板为

goo(VARIANT* theBuffer);
所以我试过了

System::Int32 buf[10];
foo(buf);
它失败了。及

Bitmap ^b;
foo(b);
它可以编译,但显然调用的函数不会为我创建.NET位图

所以我想问题是,我该如何传递这个函数一个它可以写入的内存块,然后在.NET世界中访问它


谢谢

您不能直接将
变体
转换为缓冲区


首先,您需要通过检查
theBuffer->vt
来检查存储在其中的对象类型。返回值的类型为
VARTYPE

您不能将
变量直接转换为缓冲区


首先,您需要通过检查
theBuffer->vt
来检查存储在其中的对象类型。返回的值将是
VARTYPE

类型,例如

Bitmap ^b = gcnew Bitmap(...
foo(b);

比如说

Bitmap ^b = gcnew Bitmap(...
foo(b);

好的,我实际上是在使用Axis Media Control SDK与网络摄像机接口()。我通过包装器调用的OCX函数如下所示

HRESULT GetCurrentImage(int theFormat,    [C++]
        VARIANT* theBuffer,
        LONG* theBufferSize
       );
GetCurrentImage(int theFormat, System::Object ^% theBuffer, int % theBufferSize)
包装器由Axis提供。使用.NET Reflector,我已经分解了包装器函数

public: virtual void __gc* GetCurrentImage(Int32 __gc* theFormat, [Out] Object __gc*   *theBuffer, [Out] Int32 __gc* *theBufferSize)
{
    if (this->ocx == 0)
    {
        throw __gc new InvalidActiveXStateException(S"GetCurrentImage", ActiveXInvokeKind::MethodInvoke);
    }
    this->ocx->GetCurrentImage(theFormat, out theBuffer, out theBufferSize);
}
所以它没有做任何聪明的事情,只是传递一大块内存。在C++ CLI语法中,模板看起来类似;p>
HRESULT GetCurrentImage(int theFormat,    [C++]
        VARIANT* theBuffer,
        LONG* theBufferSize
       );
GetCurrentImage(int theFormat, System::Object ^% theBuffer, int % theBufferSize)
因此,我的问题变成了如何将一大块内存传递给它进行写入,然后将其恢复回.NET对象。我试过这个

unsigned char c[100];
GetCurrentImage(0, (System::Object)c, BufSize);

但显然它不起作用。

好的,所以我实际上在使用Axis Media Control SDK与网络摄像机接口()。我通过包装器调用的OCX函数如下所示

HRESULT GetCurrentImage(int theFormat,    [C++]
        VARIANT* theBuffer,
        LONG* theBufferSize
       );
GetCurrentImage(int theFormat, System::Object ^% theBuffer, int % theBufferSize)
包装器由Axis提供。使用.NET Reflector,我已经分解了包装器函数

public: virtual void __gc* GetCurrentImage(Int32 __gc* theFormat, [Out] Object __gc*   *theBuffer, [Out] Int32 __gc* *theBufferSize)
{
    if (this->ocx == 0)
    {
        throw __gc new InvalidActiveXStateException(S"GetCurrentImage", ActiveXInvokeKind::MethodInvoke);
    }
    this->ocx->GetCurrentImage(theFormat, out theBuffer, out theBufferSize);
}
所以它没有做任何聪明的事情,只是传递一大块内存。在C++ CLI语法中,模板看起来类似;p>
HRESULT GetCurrentImage(int theFormat,    [C++]
        VARIANT* theBuffer,
        LONG* theBufferSize
       );
GetCurrentImage(int theFormat, System::Object ^% theBuffer, int % theBufferSize)
因此,我的问题变成了如何将一大块内存传递给它进行写入,然后将其恢复回.NET对象。我试过这个

unsigned char c[100];
GetCurrentImage(0, (System::Object)c, BufSize);

但显然它不起作用。

对不起,我把问题的措辞弄错了,请参见编辑。所以我并不是在写包装器。我只需要知道传递给foo(System::Object^%theBuffer)的是什么,因为它包装了一个看起来像goo(VARIANT*theBuffer)的函数。很抱歉,我的问题措辞错误,请参见编辑。所以我并不是在写包装器。我只需要知道传递给foo(System::Object^%theBuffer)的内容,因为它包装了一个看起来像goo(VARIANT*theBuffer)的函数。不幸的是,“foo”包装函数似乎没有任何形式的智能传递给未更改的版本,因此它不知道如何构造.NET对象。我认为它基本上只需要一块内存。根据我对C++/CLI的记忆,COM包装器是以这样一种方式构建的,您不必担心所有这些东西。不幸的是,“foo”包装器函数似乎没有对未更改的版本进行任何智能传递,因此它不知道如何构造.NET对象。我认为它基本上只需要一块内存。根据我对C++/CLI的记忆,COM包装器是以这样一种方式构建的,您不必担心所有这些东西。您有OCX函数的文档或示例代码吗?无法通过“VARIANT*theBuffer”猜测函数需要什么参数。您是否有OCX函数的文档或示例代码?无法通过“VARIANT*theBuffer”猜测函数需要什么参数。