从非托管DLL启动托管表格 [英] Managed Form Launched From Unmanaged DLL

查看:74
本文介绍了从非托管DLL启动托管表格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将DLL注入纯C ++应用程序中.我基本上是用更好的版本替换旧的文本编辑器,该版本支持语法突出显示,智能感知等.

我的解决方案(Visual Studio)就是这样设置的.

ManagedLibrary(使用新的文本编辑器容纳一个表格.).LIB
注入器:.EXE
DLL:.DLL

预期的流程是这样..

ManagedLibrary-> DLL-> TargetApp

问题是,我似乎无法弄清楚如何在不使我的DLL使用\ clr的情况下调用我的DLL中的托管库,并导入所有.NET内容,等等.
因此,我如何最好地做到这一点.我基本上需要调用在DLL中启动我的Form的新实例所必需的代码,但又不能使DLL成为托管项目. ?

我想做的就是从DLL中启动托管窗体,而不会在项目上造成麻烦.

有什么想法吗?

Win7的
Visual Studio C ++ 2010 Express

(我必须经过认真的练习才能完成很多工作,Express中不支持WPF \ MFC,并且新的编辑器是C#库,并且需要WPF,我最终制作了C#类库,创建了C#WPF UserControl ,在其上托管我的编辑器,在C#Windows.Forms UserControl上托管,并将其导入现在驻留在我的C ++ Windows Form上的C ++中.我只提到这一点以防万一.
------------

这仍然没有解决,我遵循以下建议,使用静态导出创建了C#.DLL,但是,任何实际使用它的尝试,仍然会提示相同的"dllmain.cpp(4):致命错误C1190:托管目标代码需要"/clr"选项"错误,导致我出现在这里.

因此,如何正确使用它,简单地引用DLL提示CLR投诉等.如果我无法参考,该如何使用?我尝试创建一个托管的C ++ .lib,告诉它"#pragma unmanaged",并进行双重包装,即..

C#:

 公共 静态  void  LaunchEditor()
{
    TextEditor t =  TextEditor();
    t.Show();
}

C ++ .Lib(#pragma不受管理)

无效 Launch()
{
  NameSpace :: LaunchEditor();
} 



解决方案

您不能在非托管可执行文件中链接常规" .NET程序集.原则上不可能.

但是,有一个后门,但不是很为人所知.我将为您提供一些有关CodeProject文章的参考.首先,这不是黑客,而是基于CLR标准.

这个想法是:您的.NET程序集应该是混合模式,同时用作.NET程序集和常规的非托管DLL.现在,您将获得一个常规" .NET程序集,并将某些方法转换为导出为非托管"方法.这是标准的IL功能.您可以将现有的.NET程序集反汇编为IL,修改IL文本,然后再次进行汇编,以获得可以链接到非托管项目的混合模式库.这可以作为一个完全自动化的构建步骤来完成,因此您不需要学习IL.

问题是:您可以访问.NET项目源代码吗?您需要将要导出的方法标记为非托管方法.可以使用添加到.NET代码中的某些特殊属性来完成此操作.如果您不能执行此操作,则仍然可以导出到非托管状态,但是必须选择其他方式导出(名称或其他方式);为此,您将需要修改现有的实用程序.

您将在我过去的解决方案中找到更多链接:
如何使用在Visual Basic 6.0中的Visual Basic 2008中创建的dll [从Unmanged Code VC ++用C#调用托管DLL [ ^ ].

解决方案本身和代码可以在以下CodeProject文章中找到:
非托管代码可以包装托管方法 [如何自动将.NET功能导出到非托管程序 [ // C#-Managed.dll 命名空间 ManagedNamespace { 公共 静态 class ManagedClass { 公共 静态 void ManagedMethod() { Form1 f = Form1(); f.Show(); } } }



然后您需要在C ++ \ CLI中创建一个cpp \ h组合..

 //  C ++-Native.h 
#pragma一次

无效 NativeCall(); 


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

使用 命名空间 ManagedNamespace;

无效 NativeCall()
{
    ManagedClass :: ManagedMethod();
} 



如果您希望此方法有效,则需要注意一些重要事项.

您将需要在解决方案资源管理器中右键单击Native.cpp,访问其属性,然后启用CLR,还需要通过将其指向托管的.dll位置来告诉它使用引用进行解析". br/>
通常,在C ++中工作时,我只会使用.H文件,但是.H文件在文件级别不支持这些附加设置,因此,使用.CPP文件是必要的,当然需要.H文件来参考,并在您的本机项目等中使用这些调用.

(您可能可以从主项目设置中解析托管DLL引用,但是您肯定要在文件级别启用CLR,否则将引发大量错误.)


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#:

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..

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


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# - 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++ - Native.h
#pragma once

void NativeCall();


// 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.)


这篇关于从非托管DLL启动托管表格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆