我正在尝试从托管C ++ / CLI调用本地Windows API。参数之一是void **。想法是该函数将分配一个内存结构,并向调用方返回一个void指针,该指针应在下一次调用时传递回API。因此,我需要在托管端为指针分配存储空间,并将引用传递给C API。我不知道该怎么做。
我尝试在调用方中声明一个void *,并通过各种运算符传递引用:&,internal_ptr <>,pin_ptr <>。我对IntPtr也做了同样的事情。我收到错误消息,指出编译器无法将其转换为void **。
这是使用IntPtr和pin_ptr的一种尝试。我在第28行(声明pin_ptr的行)上得到以下编译错误:
E0144类型“ interior_ptr<System::IntPtr>
”的值不能用于初始化类型“ cli::pin_ptr<void *>
”的实体
#include <msclr\marshal.h>
using namespace msclr::interop;
using namespace System;
namespace CLRStorage
{
public ref class CompoundFile
{
private:
String ^ pathname;
IntPtr pRootStorage;
public:
CompoundFile CompoundFile::Create(String^ path)
{
STGOPTIONS stgOptions;
stgOptions.usVersion = 1;
stgOptions.reserved = 0;
stgOptions.ulSectorSize = 4096;
stgOptions.pwcsTemplateFile = NULL;
auto cf = gcnew CompoundFile();
cf->pathname = path;
marshal_context^ context = gcnew marshal_context();
pin_ptr<void*> ppRootStorage = &cf->pRootStorage;
StgCreateStorageEx(
context->marshal_as<WCHAR*>(path),
STGM_READWRITE & STGM_CREATE,
STGFMT_DOCFILE,
0,
&stgOptions,
NULL,
IID_IStorage,
ppRootStorage);
}
};
}
答案 0 :(得分:0)
IntPtr
可以与void*
进行相互转换,但是类型不同。
由于该参数是唯一的,因此简单的解决方案是使用临时变量:
void* pRootStorage;
StgCreateStorageEx(
context->marshal_as<WCHAR*>(path),
STGM_READWRITE & STGM_CREATE,
STGFMT_DOCFILE,
0,
&stgOptions,
NULL,
IID_IStorage,
&pRootStorage);
cf->pRootStorage = IntPtr(pRootStorage);
这实际上也会快一点,因为不需要固定。
您还有一个错误的成员函数语法问题。你想要
static CompoundFile^ Create(String^ path)
代替
CompoundFile CompoundFile::Create(String^ path)
别忘了
return cf;
然后,marshal_context
不是ref class
,因此此行是错误的:
marshal_context^ context = gcnew marshal_context();
代替使用
marshal_context context;
由于它不是指针,
context.marshal_as<WCHAR*>(path)