IJW, PLEASE HELP!!!!

L

LUIS FAJARDO

What I'm trying to do is integrate an existing UNMANAGED C
6.0 application with C#.

This is what I done so far:

1.HelloWorld sample in C# - Class Library
2.HelloWorld sample in C++.NET - I'm mixing Managed and
Unmanaged blocks of code
3.HelloWorld sample in Unmanaged C 6.0 to call the C++.NET
Unmanaged block.

What is happening is that, the control never return to my
C 6.0 code.

Here is my code:

1.HelloWorld sample in C# (Class Library project)

using System;
namespace CSharpHelloWorld
{
public class Managed
{
public void HelloWorld(string message)
{
message = "Hello World!, from C# managed class";
}
}
}

2.HelloWorld sample in C++.NET (MFC DLL project)

I append the following code at the botton of the .cpp
file, I didn't touch at all the code generated by the
project wizard.

#using <mscorlib.dll>
#using System
#using CSharpHelloWorld

....
.... here code generated by the project wizard
....

//and at the botton

#pragma managed
void ManagedCode(char * message){
CSharpHelloWorld::Managed *obj;
obj->HelloWorld(message);
}
#pragma unmanaged
__declspec(dllexport) void __stdcall Show(char * message){
ManagedCode(message);
}


3.Finally, the code that I'm using to consumed the C++.NET
unmanaged function

hDLLInstance = LoadLibrary("HelloWorld");

if (hDLLInstance == (HINSTANCE) NULL)
return 0;
else
{
hShow = (Show)GetProcAddress(hDLLInstance,
"?Show@@YGXPAD@Z");
if (hShow == (Show) NULL)
{
FreeLibrary (hDLLInstance);
return 0;
}
else
hShow (lpDS->szMessageFromDll);
}
if (hDLLInstance)
{
FreeLibrary (hDLLInstance);
}
return 0;

my .h has the following declaration:
#define WINAPI __stdcall
typedef void (__stdcall *Show)(char * message);

That's it, that's my code, that's my problem, I noticed
that if instead of calling the C# HelloWorld method and
assigning directly a value to the message variable on the
C++.NET unmanaged block, it works fine, like this:

#pragma managed
void ManagedCode(char * message){
strcpy(message,"Hello World!, from C++.NET");
}

Looks like, at soon as I execute an method contained in an
external assembly it never return the control to my C 6.0
program.


Thanks in advance!!!
 
H

Huihong

I tried the code you listed here, and it seems to be
working great! The only thing is I used Managed C++
Library to create the mixed DLL, you were using MFC dll,
but I don't think that will matter.

The result from execution:

MC++ managed class
This is a simple demo to invoke a MC++ DLL
C# Managed class
This is a simple demo to invoke a MC++ DLL
Press any key to continue

Here is the code:

==================
C# Library: (to compile into HelloWorldDLL.dll)

using System;

namespace CSharpHelloWorld
{
public class SimpleDll
{
public SimpleDll()
{
}

public void HelloWorld(string msg)
{
Console.WriteLine("C# Managed
class");
Console.WriteLine(msg);
}
}
}

================
MC++ code: (to compile into MixedDLL.dll)

#include "MixedDLL.h"

#pragma managed
class Simple
{
public:
void HelloWorld(char* msg)
{
Console::WriteLine("MC++ managed class");
Console::WriteLine(msg);
}
};

#using <HelloWorldDLL.dll>

void ManagedCode(char * message){
Simple *obj = new Simple();
obj->HelloWorld(message);

CSharpHelloWorld::SimpleDll *t = new
CSharpHelloWorld::SimpleDll();
t->HelloWorld(message);
}

#pragma unmanaged

extern "C" {
__declspec(dllexport) void __stdcall Show(char * message)
{
ManagedCode(message);
}
}

========================
VC++ 6.0 code
// UseMixedDLL2.cpp : Defines the entry point for the
console application.
//

#include "stdafx.h"
#include "windows.h"

typedef void (__stdcall *Show)(char * message);

int main(int argc, char* argv[])
{
HINSTANCE hDLLInstance = LoadLibrary("MixedDLL");

if (hDLLInstance == (HINSTANCE) NULL)
return 0;
else
{
Show hShow = (Show)GetProcAddress
(hDLLInstance, "_Show@4");
if (hShow == (Show) NULL)
{
FreeLibrary (hDLLInstance);
return 0;
}
else
hShow ("This is a simple demo to
invoke a MC++ DLL");
}

if (hDLLInstance)
{
FreeLibrary (hDLLInstance);
}

return 0;
}
=========================

I can set a breakpoint anywhere in the code above, after
the Show call is no problem.

I tried very hard to locate the problems of your code,
but could not figured out what is going on. We are
developing application similar to your scenario, and I am
quite sure it works.

Huihong
..NET protector/obfuscator/linker/decompiler
Remotesoft
 
L

LUIS FAJARDO

GREAT!!!!

Yanhong Huang, It's working, thanks a lot for your help.

I don't have more questions, but I have an observation to
the code that you send to me. I noticed during my testing
that the first try didn't work, and I did the following
change to make it to work:

char msg[31] = {0};
char *msg2 = msg;

I did:
char *msg2 = "";

And then, instead of:
hShow (&msg2);
printf("%s\n",msg);

I did:
hShow (&msg2);
printf("%s\n",msg2);

Using your original code, the printf was printing again an
empty string, I don't know why, because looking at your
code, msg2 is a pointer to the msg variable, but, msg2 is
being changed during the call to C++/C#, but msg doesn't
change at all. Maybe I'm doing something wrong, but the
only modification that I did was the explained above.

Again, thank you very much for all your help!!!

-----Original Message-----
Hello Luis,

Thanks for the quick response. I think the problem is caused by reference
type paramter. So I rewrote the program and now it works fine. Please refer
to the following code:

VC 6.0 Client:

#include "stdafx.h"
#include "windows.h"
#include "stdio.h"

typedef void (__stdcall *Show)(char ** message);

int main(int argc, char* argv[])
{
HINSTANCE hDLLInstance = LoadLibrary("MCLib");
char msg[31] = {0};
char *msg2 = msg;

if (hDLLInstance == (HINSTANCE) NULL)
return 0;
else
{
Show hShow = (Show)GetProcAddress (hDLLInstance, "_Show@4");
if (hShow == (Show) NULL)
{
FreeLibrary (hDLLInstance);
return 0;
}
else
{
hShow (&msg2);
printf("%s\n",msg);
}
}

if (hDLLInstance)
{
FreeLibrary (hDLLInstance);
}

return 0;
}

Managed C++ Library:

#include "stdafx.h"

#include "MCLib.h"

#pragma managed

#using <ClassLibrary4.dll>
#using <Mscorlib.dll>

using namespace System::Runtime::InteropServices;

void ManagedCode2(char ** message)
{
String *msg = *message;
ClassLibrary4::Class1 *t = new ClassLibrary4::Class1();

t->HelloWorld2(& msg);

*message = (char*)Marshal::StringToHGlobalAnsi (msg).ToPointer();
}

#pragma unmanaged

extern "C" {
__declspec(dllexport) void __stdcall Show( char ** message)
{
ManagedCode2(message);
}


C# class libraray:

using System;

namespace ClassLibrary4
{
/// <summary>
/// Summary description for Class1.
/// </summary>
public class Class1
{
public Class1()
{
//
// TODO: Add constructor logic here
//
}
public void HelloWorld2(ref string msg)
{
msg = "C# Managed class - using reference variable";
}
}
}

Does that answer your question?


Best regards,
Yanhong Huang
Microsoft Online Partner Support

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

--------------------
!Content-Class: urn:content-classes:message
!From: "LUIS FAJARDO" <[email protected]>
!Sender: "LUIS FAJARDO" <[email protected]>
!References: <[email protected]>
<[email protected]>
<[email protected]>
!Subject: Re: IJW, PLEASE HELP!!!!
!Date: Mon, 15 Sep 2003 08:51:18 -0700
!Lines: 357
!Message-ID: <[email protected]>
!MIME-Version: 1.0
!Content-Type: text/plain;
! charset="iso-8859-1"
!Content-Transfer-Encoding: 7bit
!X-Newsreader: Microsoft CDO for Windows 2000
!X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300
!Thread-Index: AcN7oTPdZr6D457VTIaSBkrCCFjvVg==
!Newsgroups: microsoft.public.dotnet.languages.vc
!Path: cpmsftngxa07.phx.gbl
!Xref: cpmsftngxa07.phx.gbl microsoft.public.dotnet.languages.vc:28217
!NNTP-Posting-Host: tk2msftngxa12.phx.gbl 10.40.1.164
!X-Tomcat-NG: microsoft.public.dotnet.languages.vc
!
!First of all, I want to thank Huihong on the first respond
!and you Yanhong Huang on this one, for your help. So far
!so good, I'm working with the C++ managed library and
!seems to be working fine. I have a trivial question that
!I will include in this e-mail.
!
!Here is my question:
!Using the same HelloWorld sample, I want to pass a
!variable from C++ 6.0 to C# by reference, instead of
!printing a message to the Console, I want to pass the
!variable empty from C++ 6.0 and let C# changed it. Here
!is what I have so far:
!
!On C#, I'm not changing anything since I understand an
!string is always by reference:
!
!public void HelloWorld2(string msg)
!{
! msg = "C# Managed class - using reference variable";
!}
!
!Then, on C++ Managed Library
!void ManagedCode2(char * message){
! String * msg = message;
!
! CSharpHelloWorld::SimpleDll *t =
! new CSharpHelloWorld::SimpleDll();
!
! t->HelloWorld2(msg);
!
! message =
! (char*)Marshal::StringToHGlobalAnsi(msg).ToPointer();
!}
!
!The C++ 6.0 is:
!
!#include "stdafx.h"
!#include "windows.h"
!
!typedef void (__stdcall *Show2)(char * message);
!int main(int argc, char* argv[])
!{
! char msg[31] = {0};
! HINSTANCE hDLLInstance = LoadLibrary("MixedDLL");
!
! ....
!
!
! hShow2 (msg);
! printf(msg);
!
! ...
!}
!
!The variable at the printf statement is always empty. I
!noticed that the problem comes from the invocation to the
!C# method, on that point is also not getting back the
!variable changed.
!
!I think this should very trivial, but again, I'm very new
!on this matters!!!
!
!
!Thanks a lot!!!
!
!
!
!
!>-----Original Message-----
!>Hello Luis,
!>
!>Thanks for posting in the group.
!>
!>Huihong is right. I have done the same test by using
!VC++.NET managed class
!>library project. The only difference is here. I suggest
!you use it since we
!>need to change MFC DLL project setting to enable managed
!code.
!>
!>Please post here if there is any unclear.
!>
!>Best regards,
!>Yanhong Huang
!>Microsoft Online Partner Support
!>
!>Get Secure! - www.microsoft.com/security
!>This posting is provided "AS IS" with no warranties, and
!confers no rights.
!>
!>--------------------
!>!Content-Class: urn:content-classes:message
!>!From: "Huihong" <[email protected]>
!>!Sender: "Huihong" <[email protected]>
!>!References: <[email protected]>
!>!Subject: Re: IJW, PLEASE HELP!!!!
!>!Date: Sat, 13 Sep 2003 09:01:37 -0700
!>!Lines: 238
!>!Message-ID: <[email protected]>
!>!MIME-Version: 1.0
!>!Content-Type: text/plain;
!>! charset="iso-8859-1"
!>!Content-Transfer-Encoding: 7bit
!>!X-Newsreader: Microsoft CDO for Windows 2000
!>!X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300
!>!Thread-Index: AcN6EE+ayqXRPCUxQn+z075KIH+rmA==
!>!Newsgroups: microsoft.public.dotnet.languages.vc
!>!Path: cpmsftngxa06.phx.gbl
!>!Xref: cpmsftngxa06.phx.gbl
!microsoft.public.dotnet.languages.vc:28278
!>!NNTP-Posting-Host: TK2MSFTNGXA09 10.40.1.161
!>!X-Tomcat-NG: microsoft.public.dotnet.languages.vc
!>!
!>!I tried the code you listed here, and it seems to be
!>!working great! The only thing is I used Managed C++
!>!Library to create the mixed DLL, you were using MFC dll,
!>!but I don't think that will matter.
!>!
!>!The result from execution:
!>!
!>!MC++ managed class
!>!This is a simple demo to invoke a MC++ DLL
!>!C# Managed class
!>!This is a simple demo to invoke a MC++ DLL
!>!Press any key to continue
!>!
!>!Here is the code:
!>!
!>!==================
!>!C# Library: (to compile into HelloWorldDLL.dll)
!>!
!>!using System;
!>!
!>!namespace CSharpHelloWorld
!>!{
!>! public class SimpleDll
!>! {
!>! public SimpleDll()
!>! {
!>! }
!>!
!>! public void HelloWorld(string msg)
!>! {
!>! Console.WriteLine("C# Managed
!>!class");
!>! Console.WriteLine(msg);
!>! }
!>! }
!>!}
!>!
!>!================
!>!MC++ code: (to compile into MixedDLL.dll)
!>!
!>!#include "MixedDLL.h"
!>!
!>!#pragma managed
!>!class Simple
!>!{
!>!public:
!>! void HelloWorld(char* msg)
!>! {
!>! Console::WriteLine("MC++ managed class");
!>! Console::WriteLine(msg);
!>! }
!>!};
!>!
!>!#using <HelloWorldDLL.dll>
!>!
!>!void ManagedCode(char * message){
!>! Simple *obj = new Simple();
!>! obj->HelloWorld(message);
!>!
!>! CSharpHelloWorld::SimpleDll *t = new
!>!CSharpHelloWorld::SimpleDll();
!>! t->HelloWorld(message);
!>!}
!>!
!>!#pragma unmanaged
!>!
!>!extern "C" {
!>!__declspec(dllexport) void __stdcall Show(char * message)
!>!{
!>! ManagedCode(message);
!>!}
!>!}
!>!
!>!========================
!>!VC++ 6.0 code
!>!// UseMixedDLL2.cpp : Defines the entry point for the
!>!console application.
!>!//
!>!
!>!#include "stdafx.h"
!>!#include "windows.h"
!>!
!>!typedef void (__stdcall *Show)(char * message);
!>!
!>!int main(int argc, char* argv[])
!>!{
!>! HINSTANCE hDLLInstance = LoadLibrary("MixedDLL");
!>!
!>! if (hDLLInstance == (HINSTANCE) NULL)
!>! return 0;
!>! else
!>! {
!>! Show hShow = (Show)GetProcAddress
!>!(hDLLInstance, "_Show@4");
!>! if (hShow == (Show) NULL)
!>! {
!>! FreeLibrary (hDLLInstance);
!>! return 0;
!>! }
!>! else
!>! hShow ("This is a simple demo to
!>!invoke a MC++ DLL");
!>! }
!>!
!>! if (hDLLInstance)
!>! {
!>! FreeLibrary (hDLLInstance);
!>! }
!>!
!>! return 0;
!>!}
!>!=========================
!>!
!>!I can set a breakpoint anywhere in the code above, after
!>!the Show call is no problem.
!>!
!>!I tried very hard to locate the problems of your code,
!>!but could not figured out what is going on. We are
!>!developing application similar to your scenario, and I
!am
!>!quite sure it works.
!>!
!>!Huihong
!>!.NET protector/obfuscator/linker/decompiler
!>!Remotesoft
!>!
!>!>-----Original Message-----
!>!>What I'm trying to do is integrate an existing
!UNMANAGED
!>!C
!>!>6.0 application with C#.
!>!>
!>!>This is what I done so far:
!>!>
!>!>1.HelloWorld sample in C# - Class Library
!>!>2.HelloWorld sample in C++.NET - I'm mixing Managed and
!>!>Unmanaged blocks of code
!>!>3.HelloWorld sample in Unmanaged C 6.0 to call the
!>!C++.NET
!>!>Unmanaged block.
!>!>
!>!>What is happening is that, the control never return to
!>!my
!>!>C 6.0 code.
!>!>
!>!>Here is my code:
!>!>
!>!>1.HelloWorld sample in C# (Class Library project)
!>!>
!>!>using System;
!>!>namespace CSharpHelloWorld
!>!>{
!>!> public class Managed
!>!> {
!>!> public void HelloWorld(string message)
!>!> {
!>!> message = "Hello World!, from C# managed class";
!>!> }
!>!> }
!>!>}
!>!>
!>!>2.HelloWorld sample in C++.NET (MFC DLL project)
!>!>
!>!>I append the following code at the botton of the .cpp
!>!>file, I didn't touch at all the code generated by the
!>!>project wizard.
!>!>
!>!>#using <mscorlib.dll>
!>!>#using System
!>!>#using CSharpHelloWorld
!>!>
!>!>....
!>!>.... here code generated by the project wizard
!>!>....
!>!>
!>!>//and at the botton
!>!>
!>!>#pragma managed
!>!>void ManagedCode(char * message){
!>!> CSharpHelloWorld::Managed *obj;
!>!> obj->HelloWorld(message);
!>!>}
!>!>#pragma unmanaged
!>!>__declspec(dllexport) void __stdcall Show(char *
!>!message){
!>!> ManagedCode(message);
!>!>}
!>!>
!>!>
!>!>3.Finally, the code that I'm using to consumed the
!>!C++.NET
!>!>unmanaged function
!>!>
!>!>hDLLInstance = LoadLibrary("HelloWorld");
!>!>
!>!>if (hDLLInstance == (HINSTANCE) NULL)
!>!> return 0;
!>!>else
!>!>{
!>!> hShow = (Show)GetProcAddress(hDLLInstance,
!>!> "?Show@@YGXPAD@Z");
!>!> if (hShow == (Show) NULL)
!>!> {
!>!> FreeLibrary (hDLLInstance);
!>!> return 0;
!>!> }
!>!> else
!>!> hShow (lpDS->szMessageFromDll);
!>!>}
!>!>if (hDLLInstance)
!>!>{
!>!> FreeLibrary (hDLLInstance);
!>!>}
!>!>return 0;
!>!>
!>!>my .h has the following declaration:
!>!>#define WINAPI __stdcall
!>!>typedef void (__stdcall *Show)(char * message);
!>!>
!>!>That's it, that's my code, that's my problem, I noticed
!>!>that if instead of calling the C# HelloWorld method and
!>!>assigning directly a value to the message variable on
!>!the
!>!>C++.NET unmanaged block, it works fine, like this:
!>!>
!>!>#pragma managed
!>!>void ManagedCode(char * message){
!>!> strcpy(message,"Hello World!, from C++.NET");
!>!>}
!>!>
!>!>Looks like, at soon as I execute an method contained in
!>!an
!>!>external assembly it never return the control to my C
!>!6.0
!>!>program.
!>!>
!>!>
!>!>Thanks in advance!!!
!>!>.
!>!>
!>!
!>
!>.
!>
!

.
 

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

Top