Discussion:
mixing C# windows forms with C++ SDK and GetCommModemStatus()
(too old to reply)
Tony
2005-04-04 18:39:01 UTC
Permalink
How do I make a function written in C++ with Win32 functions work with my
Windows Forms Application written in C# ?

I wrote a function in C++ and tested it as a Win32 console application with
VC6. It includes initialization code and a for (;;) loop to monitor the
status of COM1 discrete input lines via a call to GetCommModemStatus() in the
SDK. When the CTS (COM1 pin 8) or RING (COM1 pin 9) signals goes true, I need
to call a function in a C# class.

I have been reviewing the System.Runtime.InteropServices and
System.Threading functions. All of the type casting is causing me a headache
... and I have written multi-threaded applications in C for Win32. My old
application is running for a couple years without rebooting Windows 2000. I
want to use my proven discrete input technique with this new .NET Windows
Application.

My C++ function is using WaitCommEvent with an OVERLAPPED structure. Do I
need to translate all of this for Interop?

I used C# because it works nicely for the GUI, database, and reports part of
my application.

How does Microsoft suggest to mix languages in this situation?
"Peter Huang" [MSFT]
2005-04-05 02:40:55 UTC
Permalink
Hi

I think you may try to write a class library and add an function to show
the winform in the classlibrary.
e.g.
public MyForm fm = new MyForm();
public void ShowForm()
{
fm.Show();
}

And then we can register the classlibrary with COM Interop by check the
register for COM interop option in the project setting.
So that we can call the .NET class just as we call a COM Object.

If you still have any concern, please feel free to post here.


Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
Tony
2005-04-05 05:29:03 UTC
Permalink
Peter, please read my original post again. I do not understand how your
response is related to my question.

I know how to write class libraries in C# and add a new method called
morework() to the MyForm class.

How do I call fm.morework() from my Win32 thread, when
GetCommModemStatus(lpdwValue &dwValue) changes dwValue from 0x60 to 0x70 ?
Post by "Peter Huang" [MSFT]
Hi
I think you may try to write a class library and add an function to show
the winform in the classlibrary.
e.g.
public MyForm fm = new MyForm();
public void ShowForm()
{
fm.Show();
}
And then we can register the classlibrary with COM Interop by check the
register for COM interop option in the project setting.
So that we can call the .NET class just as we call a COM Object.
If you still have any concern, please feel free to post here.
Best regards,
Peter Huang
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
"Peter Huang" [MSFT]
2005-04-05 08:28:53 UTC
Permalink
Hi

I am sorry if I did not make it more clearly.
We can not call the managed code(C#) from unmanaged code(C++) directly.
Because the managed code in running in the managed environment, which is
similar with java VM. The CLR will load the managed code and them Just In
Time(JIT) compiled it into unmanaged code to run on the OS. So the
unmanaged code other than the hosted CLR has not idea about where the JITed
mananged code will be, it is the CLR's job to JIT and run the unmanaged
code.

So if we wants to call the managed method in unmanaged code(C++), we need
to use COM Interop which will help to convert the managed code into a
legacy COM Object. That is point why we can call the C# from C++. Because
the C++--->COM---->CLR---->Managed code.

Otherwise we need to host the CLR ourselves, which is not a trivial thing,
Microsoft .NET: Implement a Custom Common Language Runtime Host for Your
Managed App
http://msdn.microsoft.com/msdnmag/issues/01/03/clr/default.aspx

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
Tony
2005-04-05 13:55:05 UTC
Permalink
Peter, thanks for the clarification.

Can you recomend an article for me to read in order to quickly understand
"COM Interop" for my specific case? Note: I have written COM objects with MFC
in C++ using VC6.

I have found
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconadvancedcominterop.asp
but it looks like it will take a week to read and understand ... and I will
know more than I ever wanted to know when I am finished studying.

It seems like a trivial task is complicated by the framework architecture.
Post by "Peter Huang" [MSFT]
Hi
I am sorry if I did not make it more clearly.
We can not call the managed code(C#) from unmanaged code(C++) directly.
Because the managed code in running in the managed environment, which is
similar with java VM. The CLR will load the managed code and them Just In
Time(JIT) compiled it into unmanaged code to run on the OS. So the
unmanaged code other than the hosted CLR has not idea about where the JITed
mananged code will be, it is the CLR's job to JIT and run the unmanaged
code.
So if we wants to call the managed method in unmanaged code(C++), we need
to use COM Interop which will help to convert the managed code into a
legacy COM Object. That is point why we can call the C# from C++. Because
the C++--->COM---->CLR---->Managed code.
Otherwise we need to host the CLR ourselves, which is not a trivial thing,
Microsoft .NET: Implement a Custom Common Language Runtime Host for Your
Managed App
http://msdn.microsoft.com/msdnmag/issues/01/03/clr/default.aspx
Best regards,
Peter Huang
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
"Peter Huang" [MSFT]
2005-04-06 02:07:18 UTC
Permalink
Hi

Thanks for your reply.

I suggest you read the link below. It is a good start to call .NET Type as
a COM Object in Unmanaged code, e.g. C++.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/htm
l/cpconexposingnetframeworkcomponentstocom.asp

As I have posted before, after we create a classlibrary and exposed it to
COM, the IDE will generate a typelibrary(tlb file) for us. So now we can
use the type library file to communicate with the COM Object(.NET Type
underlying). The procedure is easy and we just need to create a new class
library as we commonly do in C# and then check the register for com interop
in the project setting, then the IDE will help us registered the .NET type
as COM and generate the tlb file.

Then in the Unmanaged side(C++) we can call the COM object based on the tlb
file just as we commonly do with a VB6 or C++ written COM Object.

Using Managed Components from Unmanaged Code
http://www.15seconds.com/issue/010214.htm

As for how to use tlb in VC++, you may take a look at the link below.
http://gsraj.tripod.com/mts/vcpp/atlmts_client.html

The key point is the statement below, which will import the type the tlb
file describe into C++ class for used in C++ directly.
#import "E:\com\gopalan\ClickServer\ClickServer.tlb" no_namespace

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
Tony
2005-04-06 03:27:02 UTC
Permalink
I understand the concept of calling the COM object (my managed class) from
the unmanaged function monitor_comm();

monitor_comm() is written in C++ with Win32 functions and will make calls to
the COM object that you describe.

How do I start monitor_comm() execution? Remember from my earlier post that
monitor_comm() has initialization code before entering a for(;;) loop. Can I
run monitor_comm() as a new thread from my C# application? My main() is in
the C# project. The monitor_comm() thread should begin during Form1_Load()
Post by "Peter Huang" [MSFT]
Hi
Thanks for your reply.
I suggest you read the link below. It is a good start to call .NET Type as
a COM Object in Unmanaged code, e.g. C++.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/htm
l/cpconexposingnetframeworkcomponentstocom.asp
As I have posted before, after we create a classlibrary and exposed it to
COM, the IDE will generate a typelibrary(tlb file) for us. So now we can
use the type library file to communicate with the COM Object(.NET Type
underlying). The procedure is easy and we just need to create a new class
library as we commonly do in C# and then check the register for com interop
in the project setting, then the IDE will help us registered the .NET type
as COM and generate the tlb file.
Then in the Unmanaged side(C++) we can call the COM object based on the tlb
file just as we commonly do with a VB6 or C++ written COM Object.
Using Managed Components from Unmanaged Code
http://www.15seconds.com/issue/010214.htm
As for how to use tlb in VC++, you may take a look at the link below.
http://gsraj.tripod.com/mts/vcpp/atlmts_client.html
The key point is the statement below, which will import the type the tlb
file describe into C++ class for used in C++ directly.
#import "E:\com\gopalan\ClickServer\ClickServer.tlb" no_namespace
Best regards,
Peter Huang
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
Yan-Hong Huang[MSFT]
2005-04-07 09:48:03 UTC
Permalink
Hi,

Peter is sick today and not in the office. I will ping him when he is back
tomorrow on your question. Thanks very much for your patience.

Best regards,
Yanhong Huang
Microsoft Community Support

Get Secure! šC www.microsoft.com/security
Register to Access MSDN Managed Newsgroups!
-http://support.microsoft.com/default.aspx?scid=/servicedesks/msdn/nospam.as
p&SD=msdn

This posting is provided "AS IS" with no warranties, and confers no rights.
"Peter Huang" [MSFT]
2005-04-08 07:53:13 UTC
Permalink
Hi

From your descirption, I have some confusion, if the main() is in the C#
program, do you mean the C# program will be a EXE and the win32 programm
will be a DLL?

.NET provided two approached to interactive with unmanaged code.
1. COM Interop as we describe before.
2. P/Invoke, when we want to call win32 API, we will use the technique.

From your description, you have the main() in the C# program, i.e. you have
the C# program as the exe but the win32 as the dll(it may be a COM dll or a
legacy dll).
If so, I think you may try to expose the monitor_comm as an exported
function of a win32 legacy dll.

And the C# program will be a common windows program, and in the form_load
event, we can create a new thread, and the threadproc will p/invoke into
the DLL to call the monitor_comm function.
Also if you wants to callback into the C# code from the monitor_comm
function you may take a look in the link below.
[Unmanaged DLL]
int (WINAPI *Callback)(int);
UNMANAGEDDLL_API int fnUnmanagedDLL(int (WINAPI *fptr)(int))
{
Callback = fptr;
(*Callback)(7);
return 42;
}


public delegate int MyDel(int x);
[DllImport(@"UnmanagedDLL.dll",EntryPoint="fnUnmanagedDLL",CallingConvention
=CallingConvention.StdCall,SetLastError=true)]
extern static int fnUnmanagedDLL(MyDel ft);
private int CallBack(int x)
{
Debug.WriteLine(x);
return 1;
}
private MyDel del;//The line is necessary to prevent the del against
garbage collection.
public void ThreadProc()
{
del = new MyDel(CallBack);
fnUnmanagedDLL(del);//call into the unmanaged dll and set the managed
callback function so that it will callback later.
}
private void button1_Click(object sender, System.EventArgs e)
{
Thread th = new Thread(new ThreadStart(ThreadProc,));//Create thread to
run the fnUnmanagedDLL function
th.Start();
}


If still have concern on this issue, can you describe your scenario more
detailed?
The key point is which one will be the EXE and which one will be DLL.
e.g. win32 exe--->.NET DLL(the dll needed to be registered as COM dll)
or .NET exe ---->win32 dll(the dll can be a legacy dll or a COM dll)

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
Loading...