|
I have asked on the VC++ forum on MSDN for an app that provides somewhat of an illustration of a legacy C++ app migrated to C++/CLI.
I have been unsuccessful so far. I have a C++ console exe app that I need to wrap that in a managed class so I can call it using C#. I can post code if necessary. The program is not that big but there was a pop-up dialog that claimed otherwise.
I don't know if I should create a dll out of it and export functions or something else
Appreciate any help offered. Please re-direct if this is the wrong forum.
Al
Jer 29:11
|
|
|
|
|
|
I too have looked on the forums. It seems from numerous threads in my searches that my requirements are indeed not specific and very much in line with what developers are looking to do. That is, migrate console legacy code to that with a UI front end and wrap that in a managed dll or convert to unmanged dll and call it via IJW or P/Invoke.
One source of help is located here http://cfx.codeplex.com/[^]
I strongly recommend it as I am going through it and find a ton of useful example and resources. It seems it's been created for those asking questions similar to mine and designed as an aid to the solution
Al
Jer 29:11
|
|
|
|
|
Hi All,
I'm a developer with most of my experience in MFC, C#. Recently, I've been assigned to a project that has a Borland C++ 6 (OWL) GUI and a VC6.0 DLL that does most of the work. The VC6 DLL has around 1500 functions declared as extern "C" __stdcall (1500??!! I know... seriously! )
Now I've been delegated with the job of replacing the BOrland GUI with a new console/GUI mode application (in C#).
Hence, I decided to write a Managed C++ wrapper for this native DLL, and then write my application in C#.
The downside is that I don't have access to the source code for the VC6 DLL. I felt that a managed c++ DLL project which statically links to the .lib file for the VC6 native DLL might be the best approach.
I've created a Managed C++ CLR Class library project, which has a reference to the unmanaged VC6 .lib file (from Project Properties -> Linker -> Input -> Additional Dependencies. I've also added the header file for the DLL to this project.
I have created a managed class which wraps all the functions in the unmanaged DLL in a function.
Header file
#pragma once
#pragma comment(lib, "C:\\Sources\\lib\\native.lib")
#include "..\..\Common\include\native.h"
#include "Common.h"
#using <System.dll>
#using <System.Windows.Forms.dll>
using namespace System;
using namespace System::Windows::Forms;
namespace MC_SAMPDLL
{
public ref class MCSAMP
{
MYRESULT MC_Func1(int handle, unsigned int timeout)
{
return ::Func1(handle, timeout);
}
};
}
For example if the unmanaged function is Func1(), I'm creating a wrapper function MC_Func1().
MCSAMP::
However, when I try to call any unmanaged function from within the managed wrapper, I get linker errors as below
Error 1 error LNK2028: unresolved token (0A000012) "extern "C" enum MYRESULT __stdcall Func1(int,unsigned int)" (?Func1@@$$J18YG?AW4MYRESULT@@HI@Z) referenced in function "private: enum MYRESULT __clrcall MC_SAMPDLL::MCSAMP::MC_Func1(int,unsigned int)" (?MC_Func1@MCSAMP@MC_SAMPDLL@@$$FA$AAM?AW4MYRESULT@@HI@Z) MC_SAMPDLL.obj MC_SAMPDLL
Error 2 error LNK2019: unresolved external symbol "extern "C" enum MYRESULT __stdcall Func1(int,unsigned int)" (?Func1@@$$J18YG?AW4MYRESULT@@HI@Z) referenced in function "private: enum MYRESULT __clrcall MC_SAMPDLL::MCSAMP::MC_Func1(int,unsigned int)" (?MC_Func1@MCSAMP@MC_SAMPDLL@@$$FA$AAM?AW4MYRESULT@@HI@Z) MC_SAMPDLL.obj MC_SAMPDLL
Error 3 fatal error LNK1120: 2 unresolved externals C:\Sources\CLI SAMP\MC_SAMPDLL\Debug\MC_SAMPDLL.dll MC_SAMPDLL
The original unmanaged function is defined as extern "C" MYRESULT __stdcall Func1(int, unsigned int);
When I wrote a similar example with my own functions, it seems to work fine. However, in the case of these sources, I'm getting these link errors.
I'm at my wits end here, and the first implementation deadline is looming ahead of me. I'd be really grateful if you could help me out here...
Thanks a lot,
'The time has come,' the Walrus said,
'To talk of many things:
Of shoes -- and ships -- and sealing wax --
Of cabbages -- and kings --
And why the sea is boiling hot --
And whether pigs have wings.'
-- The Walrus and the Carpenter (by Lewis Carroll)
|
|
|
|
|
Hi,
Since I couldn't find any solution to the problem, nor are there any replies here in this forum I finally decided to go in for a C# based P/Invoke method of calling the native DLL. I know it sucks compared to the MC++ wrapper solution, but hey, at least it works!
For those who are stuck in a similar situation, they can try using the [PInvoke Interop Assistant]. This is a wonderful open source tool that makes it really simple to create an automated wrapper for native dlls. There are a few articles in MSDN magazine on how to use this tool too.
It comes with a command-line interface that allows easy porting of entire header files in the easiest manner possible. Just supply your header files to this tool, and it'll write out almost the entire wrapper declarations. Just to make sure though, you should manually examine all the ported declarations, ensuring that no mistakes are present.
Hope this helps someone else,
Bharat
'The time has come,' the Walrus said,
'To talk of many things:
Of shoes -- and ships -- and sealing wax --
Of cabbages -- and kings --
And why the sea is boiling hot --
And whether pigs have wings.'
-- The Walrus and the Carpenter (by Lewis Carroll)
|
|
|
|
|
Hi!
I'm referring on the article Calling Managed Code from Unmanaged Code and vice-versa[^], where callback functions in managed C++ code is called from unmanaged code using delegates.
On that way I have programmed a Windows Forms GUI, whose functions are delegated to unmanaged (because I had an unmanaged Interface to implement). The whole marshalling is done in one VS-project.
Now I want to compile it as DLL and call the unmanaged functions to control the GUI:
PROBLEM: To initialise the callbacks the first thing to do is to call managed code to activate the delegates and so the callbacks.
Now it would be nice to do that in the DLL-main function (entry point). But it is not possible to call managed code in DLL main, what should I do?
I want to initialize the callbacks on DLL loading, so that the functions are directly useable.
Any idea?
Thanks, cherry
|
|
|
|
|
What you can do is have a flag variable that keeps track of whether the delegates are initialized.
Then, in every exported function, the first thing you do is check to see if the delegates have been initialized.
If they have not been initialized (according to the flag variable,) then you call the initialization function from there.
That way, the initialization is performed on the thread that is calling your Dll, instead of the thread that is calling DLLMain.
|
|
|
|
|
Any chance, anyone has code to maintain the format:
(###) ###-####
for a CEdit? There are some masked edit controls, but I
cant get them to blend in with what I have. Im just looking
for something small to let me maintain the above phone
format.
Please, any response any one can give me will be greatly
appreciated.
Sincerely,
Danielle Brina
|
|
|
|
|
i'm not sure about CEdit. That looks like an MFC control. You might have better luck in the C/C++/MFC forum.[^]
if you're looking for a C++/CLI way of doing this you could use a MaskedTextBox.[^] If you must use a CEdit control you could use .net to validate the text entered using a Regular Expression.[^]
Hope this helps,
Don't be overcome by evil, but overcome evil with good
|
|
|
|
|
// IN C++ /clr
// BOXED VALUE TYPE ON GC HEAP
int ^ gc_i = gcnew int;
// WHAT EXACTLY IS THE STORAGE TYPE FOR THIS int ?
int * i = new int;
*i = 5;
// PRESUMABLY ON THE UNMANAGED HEAP, BUT HOW CAN THIS HAPPEN FOR INT?
// DOESN'T INT ALWAYS MAP TO System.Int32?
// OR DOES THE COMPILER GIVE US A NATIVE INT INSTEAD, TO PLACE ON THE UNMANGED HEAP?
|
|
|
|
|
Will5801 wrote: // WHAT EXACTLY IS THE STORAGE TYPE FOR THIS int ?
That's a native int on the CRT heap.
Will5801 wrote: // PRESUMABLY ON THE UNMANAGED HEAP, BUT HOW CAN THIS HAPPEN FOR INT?
// DOESN'T INT ALWAYS MAP TO System.Int32?
You're using int in the native context (*, new) so the compiler
can infer what int to use....the native one in this case.
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
// IN A CLR C++ PROJECT
// AN ARRAY. SHOWS IN LOCALS WINDOW AS TYPE array
array<byte> ^ a = gcnew array<BYTE>(10);
// A BYTE ARRAY. SHOWS IN LOCALS WINDOW LIKE A NATIVE ARRAY
BYTE b[10];
b[0] = 5;
// A POINTER
LPBYTE p = &b[0];
The pointer is to be passed to api as a buffer to fill
The question: is b actually a ref system.array instance and
therefore pin_ptr should be used instead? If so this must
cause some subtle bugs?
|
|
|
|
|
Will5801 wrote: The question: is b actually a ref system.array instance
No.
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
but in C#:
byte[] b; creates an instance for system.array
|
|
|
|
|
Hi all,
Recently, I am trying openCV to detect the face. All the methods work well. Now I want to compare all the methods at the same time, that means i have to use multi thread to archieve this purpose. Here is my code
In my form (Form1.h), i declared :
private: System::Threading::Thread^ trd;
and initialized the thread:
trd = gcnew Thread( gcnew ThreadStart( this->compareAlg));
and this is the compareAlg function:
private: static System::Void compareAlg ()
{
SCM *objSCM = new SCM ();
VAJ *objVAJ = new VAJ();
objVAJ ->showFaceDetect_Cam("Resource\\face.xml");
objSCM ->showFace_SkinDetect_Cam();
Thread::Sleep (0);
}
i also used a button to start the thread:
private: System::Void btnCompare_Click(System::Object^ sender, System::EventArgs^ e) {
trd->Start ();
}
The code compile well but the methods (showFaceDetect_Cam and showFace_SkinDetect) run sequently. What i want is the output of these methods appear at the same time on the screen. Can you suggest some advices, please? The thread code is found from http://msdn.microsoft.com/en-us/library/system.threading.thread.aspx
Thanks
|
|
|
|
|
bubuzzz wrote: The code compile well but the methods (showFaceDetect_Cam and showFace_SkinDetect) run sequently.
That's because you call them sequentially. If you want them to run
in parallel, you need a separate thread for each.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
|
How do I turn of command line in C++ managed forms projects from project configuration only, I already have created and compiled the project?
I am using VS 2010. But I guess that option should be the same as in VC++ 9.
Thanks,
Parth
|
|
|
|
|
I created the project ground up from empty one.
That's why I am having a command line window along with my form.
|
|
|
|
|
One more question:
How do I get the resource files to compile as separate satellite assemblies rather than in the exe itself.
Right now I have 5 language resources, all of which are getting compiled into the EXE itself.
I want them to be separate as they should be.
This resources are Form resources. I have named them appropriately with .en-US.resx, .de-De.resx etc names
|
|
|
|
|
What "command line" are you referring to?
If you mean a command window, then there shouldn't be one by default in a Forms app.
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Yes, I am talking about command window.
It is showing up. I created the app from scratch, so I guess there is some problem with configuration.
I did not create forms app using the VS wizard.
thanks,
parth
|
|
|
|
|
You need to change the subsystem to "windows". Read here[^] for more info
Don't be overcome by evil, but overcome evil with good
|
|
|
|
|
Hello,
I'm trying to create a dll in C++ with VS 2008 and creating an object MemoryStream.
So i write
MemoryStream *memStreamEncryptedData = new MemoryStream();
I included But it not work and i have a error message like this :
Error 1 error C2065: 'MemoryStream' : undeclared identifier
Error 2 error C2146: syntax error : missing ';' before identifier 'memStreamEncryptedData'
Error 3 error C2065: 'memStreamEncryptedData' : undeclared identifier
Error 4 error C2061: syntax error : identifier 'MemoryStream'
Please help me how can use it or if there is something else wich do the same work.
Thank you
|
|
|
|
|
khaliloenit wrote: Please help me how can use it or if there is something else wich do the same work.
Well you have to learn C++/CLI to use it or any other .NET classes. There are several introductory articles for C++/CLI here on CodeProject in the Articles or "CHAPTERS" part of the site.
|
|
|
|