How do I convert native pointer to managed handle? - c++-cli

I am new to c++/cli. In a c++ file with mixed code, I have a native pointer I1*. I1 is a COM interface. I want to convert the native pointer to I1^. Casting throws an error.

Use Marshal::GetObjectForIUnknown(). Cast the return value.

I expected something like IntPtr instead of the I1^

Related

Wrapping void pointer in C++/CLI and C#

I am working on C++/CLI wrapper for C static libary that is eventually used in C# application.
I have function like this in C Library.
long SubscriveEvent(void* handle,device name ,....);
long StartCaptureViceo(handle,...,...);
Here StartCaptureViceo () will use the handle from SubscriveEvent()
I nee to maintain some variable in C# for this void
Now what data type i should use in C++/CLI to Retain.
Please help me for this.
System::IntPtr

Representing IUnknown In Managed C++

I building Wrapper in C++/CLI for C Static library to be used in .NET application through C#
I have function like this in C
long My_COM_Interface( PVOID hDevice,IUnknown **pUnknown);
How to declare IUnknown ** in C++/CLI
for first argument I am using IntPtr but Not able to find out the Replacement for IUknown.
I have another COM Data type GUID in another function this is also an issue for me.
Please Help me find the relacement for data type IUnknown and GUID.
There is no replacement.
C++/CLI understands native types just fine. Include the right header files, and you can use IUnknown* like always.
I'd refer to the APIs, e.g.
public static IntPtr GetIUnknownForObject(Object o);
This API can simply be used from C++/CLR and suggests you should use IntPtr^
try using parameter like;
ref object pUnknown
and use it like
MyObject o = pUnknown as MyObject

'objType' is not defined... Actually, it is, so why is this happening?

As you seen in this picture below, for some reason my DirectCast wont except ANYTHING for the second argument. It says it requires a type, but, it won't take any object at all!
Thanks for any help! I'm using VB.net so all .net answers are acceptable :)
EDIT
Ok, so apparently I'm not giving it the right kind of type. Could somebody please clarify this? Assuming the type it needs to cast to is gridElement, what should I replace objType with?
DirectCast requires an object prototype (i.e. just giving it the intended class name) rather than a System.Type descriptor object. To cast an object using a System.Type, you will want to utilize CTypeDynamic():
Return CTypeDynamic(createElementByIdAndLayer.MemberwiseClone(), objType)
The error is essentially telling you a class with the type name "objType" does not exist.
Its expecting a "Type", not a "Type Object".
What is the return value of the function?

Copy unmanaged data into managed array

I need to copy native (i.e. unmanaged) data (byte*) to managed byte array with C++/CLI (array).
I tried Marshal::Copy (data is pointed to by const void* data and is dataSize bytes)
array<byte>^ _Data=gcnew array<byte>(dataSize);
System::Runtime::InteropServices::Marshal::Copy((byte*)data, _Data, 0, dataSize);
This gives error C2665: none of the 16 overloads can convert all parameters. Then I tried
System::Runtime::InteropServices::Marshal::Copy(new IntPtr(data), _Data, 0, dataSize);
which produces error C2664: parameter 1 cannot be converted from "const void*" to "__w64 int".
So how can it be done and is Marshal::Copy indeed the "best" (simplest/fastest) way to do so?
As you've noted, Marshal::Copy (and .NET in general), is not const-safe.
However, the usual C and C++ functions are. You can write either:
array<byte>^ data_array =gcnew array<byte>(dataSize);
pin_ptr<byte> data_array_start = &data_array[0];
memcpy(data_array_start, data, dataSize);
or to avoid pinning:
array<byte>^ data_array =gcnew array<byte>(dataSize);
for( int i = 0; i < data_array->Length; ++i )
data_array[i] = data[i];
"IntPtr" is just a wrapper around a "void *". You shouldn't need the new syntax, just use of the explicit conversion operator.
System::Runtime::InteropServices::Marshal::Copy( IntPtr( ( void * ) data ), _Data, 0, dataSize );
Should work.
All these answers dance around the real misunderstanding in the original question.. The essential mistake made is that this code:
System::Runtime::InteropServices::Marshal::Copy(new IntPtr(data),
_Data,
0,
dataSize)
is incorrect.. you don't new (or gcnew) an IntPtr. Its a value type. One of the answers shows this, but it doesn't point out the original misunderstanding. The correct code can be expressed this way:
System::Runtime::InteropServices::Marshal::Copy(IntPtr((void *)data),
_Data,
0,
dataSize)
This confused me when I first started using these constructs also..
IntPtr is a C# struct.. a value type.
The C++/CLI compiler is a bit obtuse about this. The formal definition of IntPtr is "native integer", it is not a pointer type. The C++ language however only allows conversion of void* to a pointer type. The CLI supports pointer types but there are very few framework methods that accept them. Marshal::Copy() doesn't. One of the three IntPtr constructors does.
You have to whack the compiler over the head with a cast or by using the IntPtr constructor. It is anybody's guess if this will still work on a 128-bit operating system, I'm not going to worry about it for a while.
System::Runtime::InteropServices::Marshal::Copy(new
IntPtr((void*)data), _Data, 0, dataSize);
Pay attention to (void*) which type-casts from (const void*) so new IntPtr constructor can take it as argument.

Convert Wstring to CString

i have a variable of Cstring,need to convert it to wstring.
The MultiByteToWideChar function is the base level Win32 API function to do this. Whatever library or framework you are using may offer a more convenient function that wraps this operation.