• C#调用非托管的DLL文件


    写了段C#代码实现了调用C++写的非托管DLL

    Access C++(unmanaged) APIs using C#
    1 using System;
    2  using System.IO;
    3  using System.Collections.Generic;
    4  using System.Text;
    5  using System.Reflection;
    6  using System.Reflection.Emit;
    7  /*
    8 The most important attributes of namespace System.Runtime.InteropServices are
    9 DllImportAttribute, which you use to define platform invoke methods for accessing unmanaged APIs,
    10 and MarshalAsAttribute, which you use to specify how data is marshaled between managed and unmanaged memory.
    11  */
    12  using System.Runtime.InteropServices;
    13
    14  namespace TransDLLProxyNameSpace
    15 {
    16 public struct SampleStruct
    17 {
    18 public Int32 value;
    19 };
    20
    21 class TransDLLProxy
    22 {
    23 // Dynamic Call the export function of a Native DLL.
    24
    25 // Declare the external method firstly.
    26  
    27 [DllImport("Kernel32")]
    28 // Retrieve the address of an exported function or variable from the specified DLL.
    29 public static extern int GetProcAddress(int handle, String funcname);
    30
    31 [DllImport("Kernel32")]
    32 // Map the specified executable module into the address space of the calling process.
    33 public static extern int LoadLibrary(String funcname);
    34
    35 [DllImport("Kernel32")]
    36 // Decrement the reference count of the loaded DLL.
    37 // When the reference count reaches zero, the module is unmapped from the address space of the calling process.
    38 public static extern int FreeLibrary(int handle);
    39
    40 // Get the address of the function.
    41 private static Delegate GetAddress(int dllModule, string funcName, Type t)
    42 {
    43 int addr = GetProcAddress(dllModule, funcName);
    44
    45 if (addr == 0)
    46 return null;
    47 else
    48 //Convert an unmanaged function pointer to a delegate.
    49 return Marshal.GetDelegateForFunctionPointer(new IntPtr(addr), t);
    50 }
    51
    52 //DLL function pointers.
    53 private delegate int DLL_GPFunc(string inStr);
    54 private delegate int DLL_SPFunc(ref StringBuilder outStr);
    55 private delegate int DLL_TransFunc(IntPtr header, byte[] inArray, Int32 inLength, ref IntPtr outPtr, ref Int32 outLength);
    56 private delegate int DLL_Release();
    57 //A handle to the DLL module that contains the function or variable.
    58 private int m_hModule;
    59 private DLL_GPFunc m_pGPFunc;
    60 private DLL_SPFunc m_pSPFunc;
    61 private DLL_TransFunc m_pTransFunc;
    62 private DLL_Release m_pRelease;
    63
    64 //Constructor
    65 public TransDLLProxy()
    66 {
    67 m_hModule = 0;
    68 m_pGPFunc = null;
    69 m_pSPFunc = null;
    70 m_pTransFunc = null;
    71 m_pRelease = null;
    72 }
    73 ~TransDLLProxy()
    74 {
    75 UnloadDLL();
    76 }
    77
    78 //Load DLL.
    79 public bool LoadDLL(string strDllName)
    80 {
    81 //Release handle firstly.
    82 if (m_hModule != 0)
    83 {
    84 Release();
    85 }
    86 //Get the handle to the DLL module.
    87 m_hModule = LoadLibrary(strDllName);
    88 if (m_hModule == 0)
    89 {
    90 return false;
    91 }
    92 //Get the address of the function.
    93 m_pGPFunc = (DLL_GPFunc)GetAddress(m_hModule, "GPFunc", typeof(DLL_GPFunc));
    94 m_pSPFunc = (DLL_SPFunc)GetAddress(m_hModule, "SPFunc", typeof(DLL_SPFunc));
    95 m_pTransFunc = (DLL_TransFunc)GetAddress(m_hModule, "TransFunc", typeof(DLL_TransFunc));
    96 m_pRelease = (DLL_Release)GetAddress(m_hModule, "Release", typeof(DLL_Release));
    97 return true;
    98 }
    99
    100 //Unload DLL.
    101 public void UnloadDLL()
    102 {
    103 if (m_hModule != 0)
    104 {
    105 FreeLibrary(m_hModule);
    106 m_hModule = 0;
    107 }
    108 }
    109
    110 //Proxy Functions
    111
    112 //Call DLL interface with getting parameters.
    113 public int GPFunc(string inStr)
    114 {
    115 if (m_hModule == 0|| m_pGPFunc == null)
    116 {
    117 return -1;
    118 }
    119 return m_pGPFunc(inStr);
    120 }
    121 //Call DLL interface with setting parameters.
    122 public int SPFunc(ref string outStr)
    123 {
    124 if (m_hModule == 0 || m_pSPFunc == null)
    125 {
    126 return -1;
    127 }
    128 StringBuilder tStr;
    129 tStr = new StringBuilder(256);
    130 int nResult = m_pHelp(tStr);
    131 outStr = tStr.ToString();
    132 return nResult;
    133 }
    134     //Call DLL interface to transfer struct.
    135 public int TransFunc(SampleStruct header, MemoryStream instream, ref MemoryStream outstream)
    136 {
    137 if (m_hModule == 0 || m_pTransFunc == null)
    138 {
    139 return -1;
    140 }
    141
    142 // Create a managed array.
    143 byte[] managedArray = null;
    144 int length = 0;
    145 //Assume that instream.Length == outstream.Length.
    146   IntPtr ptrOut = Marshal.AllocHGlobal((int)(instream.Length));
    147 IntPtr pHeader = Marshal.AllocHGlobal(Marshal.SizeOf(header));
    148
    149 try
    150 {
    151 Marshal.StructureToPtr(header, pHeader, true);
    152 int nResult = m_pTransFunc(pHeader, instream.ToArray(), (int)(instream.Length), ref ptrOut, ref length);
    153 if (nResult == 0 && length != 0)
    154 {
    155 managedArray = new byte[length];
    156 /*Copy data from a managed array to an unmanaged memory pointer,
    157 or from an unmanaged memory pointer to a managed array. */
    158 Marshal.Copy(ptrOut, managedArray, 0, length * sizeof(byte));
    159 outstream.Write(managedArray, 0, length);
    160 // Free the unmanaged memory.
    161 Marshal.FreeHGlobal(ptrOut);
    162 ptrOut = IntPtr.Zero;
    163 }
    164 }
    165 finally
    166 {
    167 Marshal.FreeHGlobal(pHeader);
    168 pHeader = IntPtr.Zero;
    169 }
    170 return nResult;
    171 }
    172 // Release the Resources.
    173 public int Release()
    174 {
    175 if (m_hModule == 0 || m_pRelease == null)
    176 {
    177 return -1;
    178 }
    179 return m_pRelease();
    180 }
    181 }
    182 }

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

    System.Runtime.InteropServices Namespace

    http://msdn.microsoft.com/en-us/library/9esea608%28v=VS.80%29.aspx

    MinGW下DLL编写与调用

    http://tingxx.ycool.com/post.2023760.html

    MinGW中定义DLL

    http://blog.sina.com.cn/s/blog_4ac2a65901000brf.html

    VC++动态链接库(DLL)编程深入浅出

    http://pcedu.pconline.com.cn/empolder/gj/vc/0509/699672.html

    在C#中动态调用native dll的导出函数

    http://dotnet.chinaitlab.com/CSharp/727142.html

    C#调用C++的DLL

    http://www.cnblogs.com/virusswb/archive/2008/05/30/1210520.html

    Delegate比较全面的例子(原创)

    http://www.cnblogs.com/idior/articles/100666.html

    如何:创建和使用 C# DLL(C# 编程指南)

    http://msdn.microsoft.com/zh-cn/library/3707x96z(VS.80).aspx

    在VC中创建DLL文件的方法步骤

    http://dev.yesky.com/475/7667475.shtml

  • 相关阅读:
    Activity相关
    关于JNI接口封装(将so接口调用封装到jar包)
    在android系统源码目录下编译apk
    【原创】分享一个分析函数统计案例
    【原创】Oracle函数中对于NO_DATA_FOUND异常处理的研究
    【原创】一种维护型项目升级打包的解决方案
    【原创】如何找到Oracle中哪条记录被锁
    【原创】ORA-04068: 已丢弃程序包 的当前状态研究
    【原创】CQ数据库损坏修复
    【原创】物化视图日志对性能的影响测试
  • 原文地址:https://www.cnblogs.com/pegasus923/p/1850553.html
Copyright © 2020-2023  润新知