VS2012 C# 调用 C dll

  1. 建一个解决方案,包含3个工程:WIN32 DLL 、控制台应用(c)、控制台应用(c#)
  2. WIN32 DLL代码:
    #ifdef __cpluscplus
    
    #define EXPORT extern "C" __declspec(dllexport)
    
    #else
    
    #define EXPORT __declspec(dllexport)
    
    #endif
    
    
    
    EXPORT int add(int x, int y)
    
    {
    
        return (x + y);
    
    }

     

  3. 控制台应用(c):
    #include <stdio.h>
    
    #include <windows.h>
    
    
    
    typedef int (*func)(int x, int y);
    
    
    
    int main(int argc, char *argv[])
    
    {
    
        HMODULE hDll = LoadLibrary("dll.dll");
    
        func add = (func)GetProcAddress(hDll, "add");
    
        int n = add(3, 4);
    
    
    
        printf("3 + 4 = %d\n", n);
    
    
    
        FreeLibrary(hDll);
    
        getchar();
    
    }

     

  4. 控制台应用(c#):
    using System;
    
    using System.Collections.Generic;
    
    using System.Linq;
    
    using System.Text;
    
    using System.Threading.Tasks;
    
    using System.Runtime.InteropServices;
    
    namespace exe_cs
    
    {
    
        class Program
    
        {
    
            [DllImport("dll.dll", EntryPoint = "add", CallingConvention = CallingConvention.Cdecl)]
    
            public extern static int add(int x, int y);
    
    
    
            static void Main(string[] args)
    
            {
    
                int n = add(3, 4);
    
                Console.WriteLine("3 + 4 = {0}\n", n);
    
                Console.Read();
    
            }
    
        }
    
    }

     

  5. 注意事项
    1. C# DllImport中,CallingConvention = CallingConvention.Cdecl很关键,尤其是vs2012。编译C的dll时,使用cdecl调用方式,而C#导入dll中函数时,使用Stdcall。如果不设置运行出现异常:  调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。

你可能感兴趣的:(2012)