Click here to Skip to main content
16,018,818 members
Please Sign up or sign in to vote.
3.33/5 (3 votes)
See more:
I'm injecting a DLL into a pure C++ application. I'm basically replacing an old text editor with a much nicer version that supports syntax highlighting, intellisense, etc,.

My solution(Visual Studio), is setup like this.

ManagedLibrary (Houses a Form with the new text editor.) .LIB
Injector: .EXE
DLL: .DLL

The intended flow is this..

ManagedLibrary->DLL->TargetApp

The problem is, I can't seem to figure out how to call my managed library inside my DLL without making my DLL use \clr, and import all the .NET stuff, etc,.

So, how do I best go about doing this. I basically need to call the code necessary to launch a new instance of my Form inside my DLL, but without making my DLL a managed project. ?

What I want to do, is simply launch my managed Form from the DLL, without wreaking havok on my project.

Any ideas?

Win7
Visual Studio C++ 2010 Express

(I had to jump through serious hoops to make this much work, WPF\MFC is not supported in Express, and the new editor is a C# lib, and requires WPF, I ended up making a C# class library, creating a C# WPF UserControl, hosting my editor on that, hosting that on a C# Windows.Forms UserControl, and importing that into C++, which now resides on my C++ Windows Form. I only mention this in case it would make a difference somehow.)

------------

This is still unsolved, I've followed the advice below, created a C# .DLL with static exports, however, any attempt to actually use it, still the prompts the same "dllmain.cpp(4): fatal error C1190: managed targeted code requires a '/clr' option" errors that brought me here.

So, how do I go about properly using this, simply referencing the DLL prompts the CLR complaints, etc,. If I can't reference, how can I use it? I've tried creating a managed C++ .lib, telling it "#pragma unmanaged", and double wrapping, ie,..

C#:

C#
public static void LaunchEditor()
{
    TextEditor t = new TextEditor();
    t.Show();
}

C++ .Lib (#pragma unmanaged)

void Launch()
{
  NameSpace::LaunchEditor();
}


This didn't work either, so I don't get it..
Posted
Updated 4-Aug-12 2:59am
v4
Comments
Sergey Alexandrovich Kryukov 5-Aug-11 2:23am    
Good question! A rare case: I vote 5.
The solution is not trivial at all.
If you have access to the .NET project source code, there is a very good solution of the problem.
If not, it would be more difficult but still solvable, depending on what exactly you need.

Please see my answer.
--SA

I've found a much easier solution to this problem, and figured I would share it.

You need a C# class library, and some simple code.

C#
// C# - Managed.dll
namespace ManagedNamespace
{
    public static class ManagedClass
    {
        public static void ManagedMethod()
        {
            Form1 f = new Form1();
            f.Show();
        }        
    }
}


Then you need to create a cpp\h combo in C++\CLI..

C++
// C++ - Native.h
#pragma once

void NativeCall();

C++
// C++ - Native.cpp
#pragma once
#using <mscorlib.dll>
#using <Managed.dll>
#include "Native.h"

using namespace ManagedNamespace;

void NativeCall()
{
    ManagedClass::ManagedMethod();
}


There are some important things to note if you want this to work.

You will need to right click Native.cpp in Solution Explorer, access it's properties, and enable CLR, you also need to tell it to "Resolve using references" by pointing it to your managed .dll's location.

Normally, I would just use .H files when working in C++, however, .H files do not support these additional settings at the file level, so, using a .CPP file was necessary, the .H file, is of course needed to reference, and use these calls within your native project, etc,.

(You can probably get away with resolving the managed DLL reference from the main project settings, but, you definitely want to enable CLR at the file level, it will throw tons of errors otherwise.)
 
Share this answer
 
v3
Comments
[no name] 4-Aug-12 8:34am    
Just in case it's not clear, despite enabling CLR, etc, the function "NativeCall()" acts as a native call, all the CLR stuff does is load up everything it needs to make the magic happen, ie, calling the managed code from the native world. (This solution simply creates a native wrapper for managed calls.)
You can not link a "regular" .NET assembly in your unmanaged executable. It is not possible in principle.

However, there is a back door, but it is not very well known. I'll give you a couple of references to CodeProject articles. First of all, this is not a hack but is based on the CLR standard.

The idea is: your .NET assembly should be a mixed-mode one, serving as a .NET assembly and a regular unmanaged DLL at the same time. Now, you have get a "regular" .NET assembly and convert some of the methods to be "exported to unmanaged". This is a standard IL feature. You can disassemble existing .NET assembly to IL, modify IL text and assemble again to obtain such mixed mode library you could link to your unmanaged project. This can be done as a fully automated build step, so you don't need to learn IL.

The problem is: do you have access to the .NET project source code? You need to mark the methods you want to export as unmanaged. This can be done using some special attribute you add to the .NET code. If you cannot do it, you still can export to unmanaged, but you will have to select what to export in some other way (by name or something); and for that you will need to modify existing utility.

You will find further links in my past solutions:
How can I use a dll created in Visual Basic 2008 in Visual Basic 6.0[^],
Call Managed DLL written in C# from Unmanged Code VC++[^].

Тhe solution itself and the code can be found in the following CodeProject articles:
Unmanaged code can wrap managed methods[^],
How to Automate Exporting .NET Function to Unmanaged Programs[^].


—SA
 
Share this answer
 
v2
Comments
Sergey Alexandrovich Kryukov 5-Aug-11 2:32am    
What's managed .LIB? There are not LIB in .NET.
Consider you have a .NET assembly MyLib.DLL you need to link to your unmanaged project, so MyLib.DLL would server as a library for the unmanaged project. If you have its source code, you can automate the conversion of MyLib.DLL to mixed-mode by marking desired methods to be export by some attribute. If you can do so, you can have existing utility (see last link I provided) to convert MyLib.DLL. If not -- you should look at how this utility works and write your own or think of some other way using the same idea.

Do you understand it better now?
--SA
Sergey Alexandrovich Kryukov 5-Aug-11 2:40am    
As I can understand from your question, you have this:
ManagedLibrary->DLL->TargetApp

It will produce something like TargetApp.dll you want to link to you unmanaged project (perhaps through LoadLibrary). As I understand, you don't have a source code for TargetApp.dll. Then you still can convert it to unmanaged, but the automation of this process is on you. You can learn how the utility works.

Now, if you don't have source code, there are other problems. You should understand, that you can only export the static methods (as class instantiation and using manages "this" parameter is not possible beyond the managed; it does not even makes sense), and the exported methods should only use primitive types as .NET specific classes are not really usable outside the CLR).

However I hope if you asked this question you already took this into account and know what methods to export to unmanaged. Anyway, you got the technique for doing it. Use it as is or adopt to your needs.
--SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900