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 :-)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值