C # 調用 C 函數

來源:互聯網
上載者:User
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調用?

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.