C#导出非托管方法供C/C++调用

    最近研究Notepad++插件开发,由于Notepad++使用C++开发,Notepad++也提供了C#的开发接口http://notepad-plus-plus.org/contribute/plugin-howto.html ,根据官方提供的Visual Studio模板,里面用到C#导出非托管dll的知识。



     网上找到一个类似的第三方包Nuget package. 功能与此类似。
========================================================================================

以下部分原文地址:

https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports


Unmanaged Exports




How does it work? 

Create a new classlibrary or proceed with an existing one.
Then add the UnmanagedExports  Nuget package.

This is pretty much all setup that is required.

Now you can write any kind of static method, decorate it with [DllExport] and use it from native code.
It works just like DllImport, so you can customize the marshalling of parameters/result with  MarshalAsAttribute .

During compilation, my task will modify the IL to add the required exports.

Restrictions

  • What you cannot do is use overloaded exported methods inside the same class, even if you provide them with different export names.
  • Another restriction is that you cannot call an exported method recursively.
    • This seems to be a limitation of the runtime and I did not want to wrap your code in another, hidden method to make it work.

Samples

Basic sample

Showing how to provide an export alias (the name which will be seen from consuming processes) and calling convention. (Default is stdcall, the samples use Cdecl which is used by C/C++)

C#:

class Test
{
  [DllExport( "add", CallingConvention = CallingConvention. Cdecl )]
  public static int  TestExport (int left, int right)
  {
     return left + right;
  } 
}

F#:

open  RGiesecke.DllExport
open System.Runtime.InteropServices

type Test() =
  [<DllExport("add", CallingConvention = CallingConvention.Cdecl)>]
  static member  TestExport (left : int, right : int) : int = left + right


VB.Net:

Imports  System.Runtime.InteropServices
Imports RGiesecke.DllExport

Public Module Test
   <DllExport("add")> _
   Public Function TestExport(left As Int32, right As Int32As Int32
      Return left + right
   End Function
End Module

Marshalling sample

You can also use the MarshalAsAttribute to control how the marshaller translates your .Net types into native types.
The example below shows how to mark a parameter to be returned to native code as an IUnknown-compatible interface reference.

btw, this is also how to pass objects between native and .Net ;-) 

[ ComVisible( true)] 
[ Guid( "Some GUID"), 
  InterfaceType( ComInterfaceType.InterfaceIsIUnknown)]
public interface ISample
{
    // without MarshalAs(UnmanagedType.BStr), .Net will marshal these strings as single-byte Ansi!
   // BStr is equivalent to Delphi's WideString
    String Name
   {
      // this is how to add attributes to a getter's result parameter
     [ returnMarshalAs( UnmanagedType.BStr)]
      get;
      // this is how to add attributes to a setter's value parameter
     [ paramMarshalAs( UnmanagedType.BStr)]
      set;
   }

    int DoSomething( int value);
}

public class  Sample :  ISample
{
    public  String Name{  getset; }

    public int DoSomething( int value)
   {
      return value + 1;
   }
}

static class  Exports
{
   [ DllExport]
    public static void CreateSampleInstance([ MarshalAs( UnmanagedType.Interface)] out  ISample instance)
   {
     instance =  new  Sample{ Name =  "Test" };
   }
}

Changes

  • Version 1.2.1

    • Deployed as nuget package!
      • Should install itself nicely over existing projects
    • no longer limited to C#!
      • pretty much any sane language that can create static methods with attributes should work
    • VS 2008 is no longer supported (it has no nuget support)
      • Also applies to Sharpdevelop 4.2, because my nuget scripts don't work in this version.
    • Various fixes regarding path reslution for ildasm.exe, ilasm.exe and lib.exe
      • it will no longer fail if it can't find lib.exe (it just won't produce .lib & .def files)
    • export names are escaped, so using il keywords like add won't be a problem any more
    • The task will only execute when you have selected a specific CPU target (x86, x64, Itanium) in your build options
      • Creating sub folders for each target was kinda creepy and VS' project references went crazy
    • Build events will now be fired after my task has finished (thx to Darin Higgins)
    • Uses a newer version of Mono.Cecil (0.9.5) to look for attributes
  • Version 1.1.3
    • In VS2008 and VS2010, the correct version of ILAsm/ILDasm will be used according to the TargetFramework. Only important for 2010 due to 4.0 / 2.0 runtime.
    • Temporary .def file will be removed as it isn't really required after having the .lib and .exp file.
    • Fixes to the .lib creation (export names had the real method name in the .lib, not the one that DllExport contained, while the DLL itself exported it correctly)
    • nicer Icon
    • TargetFramework is no longer set to 3.5 but left empty for the IDE to decide what makes sense (VS2005 obviously has no clue about this setting).
    • Autom. packaging of the C# project template and the archive on this page during build, to prevent uploading older versions.
  • Version 1.1.2

    • When provided with the location of lib.exe, it will create the .lib and .exp files that are required my MSVC
      • either autom. inside the VS IDE
      • having an environmental variable LibToolPath pointed to its directory
      • or adding a property LibToolPath to the project file
  • Version 1.1.1
    • I created a C# project template to make it very, very easy to setup the target and build task.
    • I also fixed some issues that could result in extreme slowdowns.
    • When you use the same export name for multiple methods, it will now create a warning which uses the pdb debug infos to point to the exact source locations.


License

Old Downloads removed...

The old downloads were removed, please use Nuget. 
I went pretty far to make those install/uninstall scripts work nicely and undestructively, so please do use them :-)
相关推荐
<p> 欢迎参加英特尔® OpenVINO™工具套件初级课程 !本课程面向零基础学员,将从AI的基本概念开始,介绍人工智能与视觉应用的相关知识,并且帮助您快速理解英特尔® OpenVINO™工具套件的基本概念以及应用场景。整个课程包含了视频的处理,深度学习的相关知识,人工智能应用的推理加速,以及英特尔® OpenVINO™工具套件的Demo演示。通过本课程的学习,将帮助您快速上手计算机视觉的基本知识和英特尔® OpenVINO™ 工具套件的相关概念。 </p> <p> 为保证您顺利收听课程参与测试获取证书,还请您于<strong>电脑端</strong>进行课程收听学习! </p> <p> 为了便于您更好的学习本次课程,推荐您免费<strong>下载英特尔® OpenVINO™工具套件</strong>,下载地址:https://t.csdnimg.cn/yOf5 </p> <p> 收听课程并完成章节测试,可获得本课程<strong>专属定制证书</strong>,还可参与<strong>福利抽奖</strong>,活动详情:https://bss.csdn.net/m/topic/intel_openvino </p> <p> 8月1日-9月30日,学习完成【初级课程】的小伙伴,可以<span style="color:#FF0000;"><strong>免费学习【中级课程】</strong></span>,中级课程免费学习优惠券将在学完初级课程后的7个工作日内发送至您的账户,您可以在:<a href="https://i.csdn.net/#/wallet/coupon">https://i.csdn.net/#/wallet/coupon</a>查询优惠券情况,请大家报名初级课程后尽快学习哦~ </p> <p> <span style="font-size:12px;">请注意:点击报名即表示您确认您已年满18周岁,并且同意CSDN基于商务需求收集并使用您的个人信息,用于注册OpenVINO™工具套件及其课程。CSDN和英特尔会为您定制最新的科学技术和行业信息,将通过邮件或者短信的形式推送给您,您也可以随时取消订阅不再从CSDN或Intel接收此类信息。 查看更多详细信息请点击CSDN“<a href="https://passport.csdn.net/service">用户服务协议</a>”,英特尔“<a href="https://www.intel.cn/content/www/cn/zh/privacy/intel-privacy-notice.html?_ga=2.83783126.1562103805.1560759984-1414337906.1552367839&elq_cid=1761146&erpm_id=7141654/privacy/us/en/">隐私声明</a>”和“<a href="https://www.intel.cn/content/www/cn/zh/legal/terms-of-use.html?_ga=2.84823001.1188745750.1560759986-1414337906.1552367839&elq_cid=1761146&erpm_id=7141654/privacy/us/en/">使用条款</a>”。</span> </p> <p> <br /> </p>
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页