C++ HWND to and from C# and Managed C++?

  • Thread starter Thread starter Guest
  • Start date Start date
Seems like you could use a void*:

C#:
MyMethod(this.Handle.ToPointer());

C++:
public:
void MyMethod(void* handle)
{
HWND l_wnd(handle);
....
}

However, that seems to require the unsafe keyword and that the code is
compiled with the /unsafe parameter. However 2, the descriptions I have found
about how to add this compiler option (e.g.
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=122815&SiteID=1) talks
about a Build subfolder under Configuration Properties. I have: General,
Debugging, C/C++, Linker, Manifest Tool, Resources, XML Document Generation,
Browse Information, Build Events, Custom Build setup, and web deployment.
Nothing called Build. Where do I find this setting?

Perhaps this is not the best / simplest way to do it. Then I would
appreciate if I could be told this.
 
What I really want to do is to pass a C# equivalent to the HWND structure in
C++ and pass it as a pointer to a HWND in managed C++. I need to get this
window handle to a third party unmanaged C++ function to assign the third
party software to render video onto this window.
 
I found it.

Joachim said:
Seems like you could use a void*:

C#:
MyMethod(this.Handle.ToPointer());

C++:
public:
void MyMethod(void* handle)
{
HWND l_wnd(handle);
...
}

However, that seems to require the unsafe keyword and that the code is
compiled with the /unsafe parameter. However 2, the descriptions I have found
about how to add this compiler option (e.g.
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=122815&SiteID=1) talks
about a Build subfolder under Configuration Properties. I have: General,
Debugging, C/C++, Linker, Manifest Tool, Resources, XML Document Generation,
Browse Information, Build Events, Custom Build setup, and web deployment.
Nothing called Build. Where do I find this setting?

Perhaps this is not the best / simplest way to do it. Then I would
appreciate if I could be told this.
 
Joachim said:
What I really want to do is to pass a C# equivalent to the HWND structure in
C++ and pass it as a pointer to a HWND in managed C++. I need to get this
window handle to a third party unmanaged C++ function to assign the third
party software to render video onto this window.


A HANDLE is represented by an IntPtr in the framework so you simply have to pass a reference
to the IntPtr variable holding the HWND.

IntPtr hwnd = myForm.Handle;
....
// call unmanaged function expecting a pointer to a HWND.
UnmanagedFunc(ref hwnd);

Willy.
 
Thanks Willy,

However, I can't get that working:

Argument '2': cannot convert from 'ref System.IntPtr' to
'HWND__*' F:\Development\Test\MCPP\TestApp\Form1.cs 67 21 TestApp

Regards,
Joachim
 
That was for a HWND and not a HWND*. But for HWND the error is similar:

Argument '2': cannot convert from 'ref System.IntPtr' to
'HWND__**' F:\Development\Test\MCPP\TestApp\Form1.cs 67 21 TestApp
 
Joachim said:
That was for a HWND and not a HWND*. But for HWND the error is similar:

Argument '2': cannot convert from 'ref System.IntPtr' to
'HWND__**' F:\Development\Test\MCPP\TestApp\Form1.cs 67 21 TestApp

Can you show us the prototype you're using?

Where is this function you're calling, whose second argument you can't
find the type for?

To get that HWND__** in C#, you'd need to use an unsafe block. Where did
the function come from?

-- Barry
 
Joachim said:
Thanks Willy,

However, I can't get that working:

Argument '2': cannot convert from 'ref System.IntPtr' to
'HWND__*' F:\Development\Test\MCPP\TestApp\Form1.cs 67 21 TestApp

Regards,
Joachim


Please show us your "DllImport" declaration, your C function prototype and how you declared
HWND__ in C#.

Willy.
 
// This is the main DLL file.

#include "stdafx.h"
#include "MCPP.h"

namespace MCPP
{
/*static */ bool MyManagedCPPClass::Test(
HWND* parent_wnd,
HWND* overlay)
{
//Some code...
}
}


//From C#: (I included the reference dll)

IntPtr l_parent_hwnd = Handle;
IntPtr l_hwnd = m_panel1.Handle;
if (!MyManagedCPPClass.Test(
0,
ref l_parent_hwnd,
ref l_hwnd,
 
Joachim said:
// This is the main DLL file.

#include "stdafx.h"
#include "MCPP.h"

namespace MCPP
{
/*static */ bool MyManagedCPPClass::Test(
HWND* parent_wnd,
HWND* overlay)
{
//Some code...
}
}


//From C#: (I included the reference dll)

IntPtr l_parent_hwnd = Handle;
IntPtr l_hwnd = m_panel1.Handle;
if (!MyManagedCPPClass.Test(
0,
ref l_parent_hwnd,
ref l_hwnd,



I'm still missing the PInvoke declaration, anyway you need something like this:

[DllImport("somedll")]
...... Test(ref IntPtr parent_wnd, ref IntPtr overlay);

but the point is, do you nee to pass a pointer to a HWND or do you need a HWND? guess not!
Note that a HWND (a HANDLE) itself is a pointer to a void. So, IMO you need to declare your
C++ function as taking two HWND, and in C# you simply need to pass an IntPtr instead of a
ref IntPtr.

Willy.
 
Thats odd. I can use the function without that declaration...

Willy Denoyette said:
Joachim said:
// This is the main DLL file.

#include "stdafx.h"
#include "MCPP.h"

namespace MCPP
{
/*static */ bool MyManagedCPPClass::Test(
HWND* parent_wnd,
HWND* overlay)
{
//Some code...
}
}


//From C#: (I included the reference dll)

IntPtr l_parent_hwnd = Handle;
IntPtr l_hwnd = m_panel1.Handle;
if (!MyManagedCPPClass.Test(
0,
ref l_parent_hwnd,
ref l_hwnd,



I'm still missing the PInvoke declaration, anyway you need something like this:

[DllImport("somedll")]
...... Test(ref IntPtr parent_wnd, ref IntPtr overlay);

but the point is, do you nee to pass a pointer to a HWND or do you need a HWND? guess not!
Note that a HWND (a HANDLE) itself is a pointer to a void. So, IMO you need to declare your
C++ function as taking two HWND, and in C# you simply need to pass an IntPtr instead of a
ref IntPtr.

Willy.
 
How would that declaration look like when I have a class?

Regards,
Joachim

Joachim said:
Thats odd. I can use the function without that declaration...

Willy Denoyette said:
Joachim said:
// This is the main DLL file.

#include "stdafx.h"
#include "MCPP.h"

namespace MCPP
{
/*static */ bool MyManagedCPPClass::Test(
HWND* parent_wnd,
HWND* overlay)
{
//Some code...
}
}


//From C#: (I included the reference dll)

IntPtr l_parent_hwnd = Handle;
IntPtr l_hwnd = m_panel1.Handle;
if (!MyManagedCPPClass.Test(
0,
ref l_parent_hwnd,
ref l_hwnd,



I'm still missing the PInvoke declaration, anyway you need something like this:

[DllImport("somedll")]
...... Test(ref IntPtr parent_wnd, ref IntPtr overlay);

but the point is, do you nee to pass a pointer to a HWND or do you need a HWND? guess not!
Note that a HWND (a HANDLE) itself is a pointer to a void. So, IMO you need to declare your
C++ function as taking two HWND, and in C# you simply need to pass an IntPtr instead of a
ref IntPtr.

Willy.
 
If I remove the class declaration and only have static functions I get the
following error

"Unable to find an entry point named 'Test' in DLL 'MCPP.dll'."


[DllImport(DllName, CallingConvention = CallingConvention.Winapi,
CharSet = CharSet.Ansi)]
static extern bool Test(
ref IntPtr one, ref IntPtr two);


//The managed cpp header
#pragma once

#include "windows.h"
#include "Common.h"

namespace MCPP
{
static bool Test(
HWND parent_wnd,
HWND overlay);
}


Joachim said:
How would that declaration look like when I have a class?

Regards,
Joachim

Joachim said:
Thats odd. I can use the function without that declaration...

Willy Denoyette said:
// This is the main DLL file.

#include "stdafx.h"
#include "MCPP.h"

namespace MCPP
{
/*static */ bool MyManagedCPPClass::Test(
HWND* parent_wnd,
HWND* overlay)
{
//Some code...
}
}


//From C#: (I included the reference dll)

IntPtr l_parent_hwnd = Handle;
IntPtr l_hwnd = m_panel1.Handle;
if (!MyManagedCPPClass.Test(
0,
ref l_parent_hwnd,
ref l_hwnd,





I'm still missing the PInvoke declaration, anyway you need something like this:

[DllImport("somedll")]
...... Test(ref IntPtr parent_wnd, ref IntPtr overlay);

but the point is, do you nee to pass a pointer to a HWND or do you need a HWND? guess not!
Note that a HWND (a HANDLE) itself is a pointer to a void. So, IMO you need to declare your
C++ function as taking two HWND, and in C# you simply need to pass an IntPtr instead of a
ref IntPtr.

Willy.
 
When I use

__declspec(dllexport)

inf front of a function which handles any kind of System::String^ I get a
compilation error. Will it do this to all managed c++ specific constructs?
What am I doing wrong? Is there another way to export functions in Managed
C++?

Joachim said:
If I remove the class declaration and only have static functions I get the
following error

"Unable to find an entry point named 'Test' in DLL 'MCPP.dll'."


[DllImport(DllName, CallingConvention = CallingConvention.Winapi,
CharSet = CharSet.Ansi)]
static extern bool Test(
ref IntPtr one, ref IntPtr two);


//The managed cpp header
#pragma once

#include "windows.h"
#include "Common.h"

namespace MCPP
{
static bool Test(
HWND parent_wnd,
HWND overlay);
}


Joachim said:
How would that declaration look like when I have a class?

Regards,
Joachim

Joachim said:
Thats odd. I can use the function without that declaration...

:

// This is the main DLL file.

#include "stdafx.h"
#include "MCPP.h"

namespace MCPP
{
/*static */ bool MyManagedCPPClass::Test(
HWND* parent_wnd,
HWND* overlay)
{
//Some code...
}
}


//From C#: (I included the reference dll)

IntPtr l_parent_hwnd = Handle;
IntPtr l_hwnd = m_panel1.Handle;
if (!MyManagedCPPClass.Test(
0,
ref l_parent_hwnd,
ref l_hwnd,





I'm still missing the PInvoke declaration, anyway you need something like this:

[DllImport("somedll")]
...... Test(ref IntPtr parent_wnd, ref IntPtr overlay);

but the point is, do you nee to pass a pointer to a HWND or do you need a HWND? guess not!
Note that a HWND (a HANDLE) itself is a pointer to a void. So, IMO you need to declare your
C++ function as taking two HWND, and in C# you simply need to pass an IntPtr instead of a
ref IntPtr.

Willy.
 
Joachim said:
Thats odd. I can use the function without that declaration...

Sorry, got confused by the C++ method signature, now I see that this is managed C++, note
that you should specify which dialect of C++ you are talking about when posting, we have
MC++ (you shouldn't use any longer) and C++/CLI.
Anyway, you don't need the DllImport in your C# code, your C++/CLI method should take an
IntPtr.
When passing the IntPtr to umanaged code you need to convert the IntPtr to a point to void,
using IntPtr::ToPointer()

C#
MyManagedCPPClass c = new MyManagedCPPClass();
c.Test(IntPtr parent, IntPtr overlay-);

//C++/CLI
/*static */ bool MyManagedCPPClass::Test(
System::IntPtr parent_wnd,
System::IntPtr overlay)

....
// make it an HWND
HWND hwnd = parent_wnd.ToPointer();
// call native function expecting a HWND param..
Func(HWND hwnd..)
...

Willy.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top