Preserve C++ Pointer in C#

162 views Asked by At

I am writing a little Program in C# which includes a C++ Dll.

In C++, there are many classes which needed to be instanced and left for later use. This looks like the following function:

C++:
__declspec(dllexport) FrameCapture* GetFrameCapturer(HWND windowHandle) {
    ProcessWindow* window = ProcessWindowCollection::GetInstance()->FindWindow(windowHandle);
    FrameCapture* capture = new FrameCapture(window);
    return capture;
}

As you can see I just create a FrameCapture class and return a Pointer to it.

This Pointer is stored in C# as an IntPtr.

C#:
[DllImport("<dllnamehere>")]
public static extern IntPtr GetFrameCapturer(IntPtr windowHandle);

This works really well so far. But if I use that Pointer to get an Instance of FrameCapture

C++:
__declspec(dllexport) BITMAPFILEHEADER* GetBitmapFileHeader(FrameCapture* frameCapturer) {
    return frameCapturer->GetBitmapFileHeader();
}

the class will be completely empty. How do I get the Instance of the Class I initialized in step one?

EDIT:

I did some testing and replaced the Pointers with integers which are better to look at.

I casted 'capture' to an Int32 and returned this instead. In my testcase it returned byte(208,113,244,194). This values are, as expected, in C++ and C# the same.

But, now it becomes odd.

If I pass this Int32 into 'GetBitmapFileHeader' the value becomes suddenly byte(184,231,223,55).

That's not even close! I thought of Little <-> Big Endian or something like this but, this is a whole new Memoryblock?

The same behavior will go on with the IntPtr.

As requested I post also the Import of 'GetBitmapFileHeader'

[DllImport("<dllnamehere>")]
public static extern tagBITMAPFILEHEADER GetBitmapFileHeader(IntPtr capturerHandle);
1

There are 1 answers

0
Dropye On BEST ANSWER

Okay, I got it.

See this import from C#.

C#:
[DllImport("<dllnamehere>")]
public static extern tagBITMAPFILEHEADER GetBitmapFileHeader(IntPtr capturerHandle);

Its wrong!

The function now returns an IntPtr wich works completely fine.

This is the new Setup:

C++:

    __declspec(dllexport) void* __stdcall GetBitmapFileHeader(void* frameCapturer) {

        FrameCapture* cap = (FrameCapture*)frameCapturer;
        return cap->GetBitmapFileHeader();
    }

C#:

[DllImport("libWinCap.dll", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr GetBitmapFileHeader(IntPtr frameCapturer);

[...]
//calling
IntPtr ptr = GetBitmapFileHeader(m_capturerHandle);
m_bitmap.m_fileHeader = (tagBITMAPFILEHEADER)Marshal.PtrToStructure(ptr, typeof(tagBITMAPFILEHEADER));

Iam only moving Pointers now and use PtrToStructure to read the Memory.

Also, Thanks for every comment.