zoukankan      html  css  js  c++  java
  • C # 调用 C 函数


    c 代码:
    #include <stdio.h>
    #include <assert.h>
    #define MAXLEN 1000
    int getline(char[] ,int);

    //供C# 调用 __declspec
    __declspec(dllexport) void reverseline(char dest[],const char source[]);

    int main(int argc, char *argv[])
    {
        char currentline[MAXLEN];
        int maxcount=0;
        int currentlen=0;
        char  resultline[MAXLEN];
        while(currentlen=getline(currentline,MAXLEN))
        {
              reverseline(resultline,currentline);
              printf("\n %s \n",resultline);
        }

        

        return 0;
    }
    int getline(char line[],int len)
    {
        //printf("-------start getline-----------------------\n");
        char c;
        int i=0;
        for(;(i<len&&(c=getchar())!=EOF &&(c!='\n'));i++)
        {
            
            line[i]=c;
            //printf(" line[%d]=%c",i,c);
        }

        line[i]='\0';
        //printf("\n line[%d]=null \n",i+1);

        //printf("-------end getline-----------------------\n");
        return i;
    }

    void reverseline(char dest[],const char source[])
    {
        
        int i=0;
        int len=0;
        for(i=0;i<MAXLEN;i++)
        {
            if(source[i]=='\0')
            {
                len=i;
                break;
            }
            //dest[i]=source[i];
        }

        //printf("\nlen =%d \n",len);

        for(i=0;i<len;i++)
        {
            dest[len-1-i]=source[i];
            //printf(" dest[%d]=%c",len-1-i,dest[len-1-i]);
        }

        dest[len]='\0';
        

    }

    使用 ms cl.exe ,生成 dll

    cl.exe reverseline.c /LD
    注意是/LD 是大写,如果写成 /ld,直接被cl 忽略

    正常情况写的编译输出:
    reverseline.c
    Microsoft (R) Incremental Linker Version 9.00.30729.01
    Copyright (C) Microsoft Corporation.  All rights reserved.

    /out:reverseline.dll
    /dll
    /implib:reverseline.lib
    reverseline.obj
       正在创建库 reverseline.lib 和对象 reverseline.exp

    导出函数不加__declspec(dllexport) 编译输出:
    reverseline.c
    Microsoft (R) Incremental Linker Version 9.00.30729.01
    Copyright (C) Microsoft Corporation.  All rights reserved.

    /out:reverseline.dll
    /dll
    /implib:reverseline.lib
    reverseline.obj

    C# 代码:把 reverseline.dll  拷到  C# 生成的 .exe的目录
    C# 代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices;

    namespace CallCLib
    {
        class CLib
        {
            [DllImport("reverseline.dll")]
            public static extern void  reverseline(StringBuilder  dest, StringBuilder  surce);
        }
        class Program
        {
            static void Main(string[] args)
            {
                //char[] a = { '1','2','3'};
                //char[] b=new char[]{};
                StringBuilder  a = new StringBuilder ("123");
                StringBuilder  b =new StringBuilder ();
                CLib.reverseline(b, a);

                Console.WriteLine("a={0} b={1}",a,b);

                Console.Read();
            }
        }
    }
    运行后生成的结果:
    a=123 b=321

    问题:
    (1)如果按以下调用
     public static extern void  reverseline(char[]  dest, char[]  surce);

    char[] a = { '1','2','3'};
    char[] b=new char[]{};

    CLib.reverseline(b, a);
    异常:
    未处理 System.AccessViolationException
      Message="尝试读取或写入受保护的内存。这通常指示其他内存已损坏。"
      Source="CallCLib"
      StackTrace:
           在 CallCLib.CLib.reverseline(Char[] dest, Char[] surce)
           在 CallCLib.Program.Main(String[] args) 位置 E:\lhb\Program\CallCLib\CallCLib\Program.cs:行号 23
           在 System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
           在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
           在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           在 System.Threading.ThreadHelper.ThreadStart()
      InnerException:
    (2)如果按以下调用
     public static extern void  reverseline(char[]  dest, char[]  surce);

    string a = "123";
    string b="";

    CLib.reverseline(b, a);

    运行后生成的结果:
    a=123 b=

    (2)如果在c 的导出函数不加__declspec(dllexport)   ,直接是 void reverseline(char dest[],const char source[]) ;
    异常:
    未处理 System.EntryPointNotFoundException
      Message="无法在 DLL“reverseline.dll”中找到名为“reverseline”的入口点。"
      Source="CallCLib"
      TypeName=""
      StackTrace:
           在 CallCLib.CLib.reverseline(Char[] dest, Char[] surce)
           在 CallCLib.Program.Main(String[] args) 位置 E:\lhb\Program\CallCLib\CallCLib\Program.cs:行号 23
           在 System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
           在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
           在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           在 System.Threading.ThreadHelper.ThreadStart()
      InnerException:

    问题:是不是 用c 标准库写的函数,不修改c 的源码(比如添加__declspec,或定义def 文件),就不能被.net调用?









  • 相关阅读:
    Unity3D脚本使用:物体调用物体
    Unity3D脚本使用:游戏对象访问
    Unity3D 浏览工具
    spring的工厂方法
    spring运用的设计模式
    Jquery ajax 与 lazyload的混合使用(实现图片异步加载)
    关于线程安全的一点总结
    lazyload的使用心得
    ajax原理及应用
    $.ajax和$.load的区别
  • 原文地址:https://www.cnblogs.com/hbb0b0/p/1786766.html
Copyright © 2011-2022 走看看