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
来源:oschina
链接:https://my.oschina.net/happytor/blog/3159545