我使用本教程为基础的我的代码在32位的非托管的DLL https://code.msdn.microsoft.com/CppHostCLR-e6581ee0如何将IntPtr传递给来自非托管C++ CLR托管代码的方法?
比方说,我想打电话给TestIntPtr
public class IntPtrTester
{
public static void TestIntPtr(IntPtr p)
{
MessageBox.Show("TestIntPtr Method was Called");
}
public static void TestInt(int p)
{
MessageBox.Show("TestInt Method was Called");
}
}
如何传递IntPtr的参数,如果在C++方面,它代表了处理? TestInt工作,但对于TestIntPtr我得到的错误,找不到该方法。这是因为参数的类型是错误的。
在从教程代码为TestInt我用
// HDC dc;
// The static method in the .NET class to invoke.
bstr_t bstrStaticMethodName(L"TestInt");
SAFEARRAY *psaStaticMethodArgs = NULL;
variant_t vtIntArg((INT) dc);
variant_t vtLengthRet;
...
psaStaticMethodArgs = SafeArrayCreateVector(VT_VARIANT, 0, 1);
LONG index = 0;
hr = SafeArrayPutElement(psaStaticMethodArgs, &index, &vtIntArg);
if (FAILED(hr))
{
wprintf(L"SafeArrayPutElement failed w/hr 0x%08lx\n", hr);
goto Cleanup;
}
的问题是,什么是TestIntPtr正确的代码
// The static method in the .NET class to invoke.
// HDC dc;
bstr_t bstrStaticMethodName(L"TestIntPtr");
SAFEARRAY *psaStaticMethodArgs = NULL;
variant_t vtIntArg((INT) dc); // what do I have to write here?
variant_t vtLengthRet;
我曾尝试:
variant_t vtIntArg((INT) dc);
variant_t vtIntArg((UINT) dc);
variant_t vtIntArg((long) dc);
variant_t vtIntArg((UINT32) dc);
variant_t vtIntArg((INT32) dc);
也许CLR预期的IUnknown IntPtr在那里?但是如何构建这样的实例呢?我试图用这个API调用IntPtr构造函数,但它返回V_INTEGER类型的变体,所以这是闭环。
我知道我可以使用COM以及如何使用DllExports破解暴露的C#库,我也可以改变C#部分接受只是INT或UINT。但所有这些方式都与这个问题无关。
目前,它为我的作品与下面的C#帮手
public class Helper
{
public static void help(int hdc)
{
IntPtrTester.TestIntPtr(new IntPtr(hdc));
}
}
和
variant_t vtIntArg((INT32) dc);
在C++中。但这很丑陋,因为我需要这个帮手来帮助我无法影响的图书馆。
嗯,我从来没有尝试过从C++端做这个,但一般来说,'IntPtr'大致等同于'void *'。它当然不是COM对象,它甚至不必是有效的指针,但这是最接近的表示。请注意,'IntPtr'绝对*不是句柄* - 它是一个指针,不再是。如果您需要传递句柄,则需要使该函数接受句柄,而不是'IntPtr'。没有保证句柄是指针大小的。 – Luaan
如果你的C++项目的目标是x64,你还没有尝试过LONGLONG。看看CoreCLR代码,我没有看到很多理由对此持乐观态度。他们确实添加了VT_INT_PTR标记类型,但尚未将其添加到CLR中。 –
我已编辑该问题以添加位数并描述已知的解决方法。 – xdenser