Pascal基础(六)-C语言动态链接库

谁说我不能喝 提交于 2020-02-26 03:11:55

Pascal 调用 C语言 开发的 动态链接库, 环境: Fedora 31, gcc 9.2.1, fpc 3.0.4

C 语言的编译和链接相对简单(相对于C++), 所有只有C语言的动态链接库的调用方法记录,C++本身就复杂,编译和链接自然也复杂, 个人猜测ABI 一致也相对较难,暂不涉及

有时间会记录一篇Pascal编译为dll, 供C语言调用的例子

C语言动态链接库源码

//simplemath.h
#ifndef SIMPLEMATH_H
#define SIMPLEMATH_H
#include <stdlib.h>
typedef enum LoLevel_{
    llDebug,
    llInfo,
    llWarn,
    llError,
    llFatal
}LogLevel;
typedef struct Student_{
    int id;
    char name[20];
}Student;

/*
int plus_int(int a,int b);
int max_int(int x,int y); 
void swap_int(int* x,int* y);
int swap_void(void *a,void* b,size_t t);
void logger(char* msg,LogLevel level);
*/
#endif
//simplemath.c
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#include "simplemath.h"

int max_int(int x,int y){
    if (x>y){
        return x;
    }else{
        return y;
    }
}

int plus_int(int x,int y){
    return x+y;
}
int swap_int(int* a,int* b){
    int c = *a;
    *a = *b;
    *b = c;
    return 0;
}
int swap_void(void* a,void* b,size_t t){
    char* c = malloc(t);
    if(c==NULL){
        return -1;
    }
    memcpy(c,a,t);
    memcpy(a,b,t);
    memcpy(b,c,t);
    free(c);
    return 0;
}
int current_date(char* buffer,size_t t){
    time_t rawtime;
    struct tm* timeinfo;
    time(&rawtime);
    timeinfo = localtime(&rawtime);
    strftime(buffer,t,"%Y-%m-%d %H:%M:%S",timeinfo);
    return 0;
}
const char* get_name(LogLevel level){
    switch(level){
        case llInfo:
            return "Info";
        case llDebug:
            return "Debug";
        default:
            return "Unkown";
    }
}
void logger(const char* msg, LogLevel level){
    char buffer[20];
    current_date(buffer,20);
    printf("%s - %s - %s\n",buffer,get_name(level), msg);
}
void student_tostring(Student* student, char* buffer){
    sprintf(buffer,"id: %d , name: %s\n",student->id,student->name);
}

pascal的调用代码

//main.pas


Program main;
{$mode objfpc}{$H+}

Uses SysUtils;

Type LogLevel = (llDebug,llInfo,llWarn,llError,llFatal);

Type Student = Record
  id: integer;
  name: string[20];
End;

Function max_int(a,b:integer): integer;
stdcall;
external 'libsm';
Function plus_int(x,y:integer): integer;
stdcall;
external 'libsm';
Function swap_int(Var x:integer;Var y:integer): integer;
stdcall;
external 'libsm';
Function swap_void(x:pchar;y:pchar;t:integer): integer;
stdcall;
external 'libsm';
Procedure logger(msg:pchar;level:LogLevel);
stdcall;
external 'libsm';

Type PStudent = ^Student;
Procedure student_tostring(s:PStudent;buffer:pchar);
stdcall;
external 'libsm';


Var a,b: integer;
  c,d: pchar;
  s: Student;
  buffer: pchar;
Begin
  a := 10;
  b := 20;

  writeln(max_int(a,b));
  writeln(plus_int(a,b));
  swap_int(a,b);
  writeln(a,',',b);
  c := @a;
  d := @b;
  swap_void(c,d,sizeof(a));
  writeln(a,',',b);
  logger('Hello world',llInfo);
  s.id := 20;
  s.name := 'Jerry';
  buffer := stralloc(80);
  student_tostring(@s,buffer);
  logger(buffer,llInfo);
  strdispose(buffer);
End.

makefile

main.elf:main.c libsimplemath.a
	gcc main.c libsimplemath.a -o main.elf
main2.elf:main.c libsm.so
	export LD_LIBRARY_PATH=.
	gcc -o main2.elf main.c -lsm -L.
mainp.elf:main.pas libsm.so
	ptop main.pas  main.pas
	export LD_LIBRARY_PATH=.
	fpc -Fl. main.pas -omainp.elf
libsm.so:simplemath.c simplemath.h
	gcc --shared -o libsm.so -fPIC simplemath.c simplemath.h
libsimplemath.a:simplemath.o
	ar -q libsimplemath.a simplemath.o
simplemath.o:simplemath.c simplemath.h
	gcc -c simplemath.c  -o simplemath.o
clean:
	rm -f *.elf
	rm -f *.o
	rm -f *.a
	rm -f *.so
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!