· 

WSLでLinuxのDLL作成

 

先日作ったstudy1.dllをLinux用のDLLすなわちstudy1.soとしてビルドする。

Makefileをちょこちょこっとへんこうして、ソースファイル中の__stdcallはLinuxではいらんので、#define文で__stdcall亡き者にする置換をして、defファイルの役割をするmapファイルを作成する。

Makefile_Lin
TARGETNAME=study1
CC=gcc
CXX=g++
LINK=gcc
CFLAGS= -fPIC -O4 -Wall -c
LFLAGS= -shared  -static-libgcc -static-libstdc++ -Wl,--version-script,$(TARGETNAME).map -o $(TARGETNAME).so
#LFLAGS= -shared -Wl,--version-script,$(TARGETNAME).map -o $(TARGETNAME).so
OBJS= $(TARGETNAME).o nijo.o tasu.o

ALL : $(TARGETNAME).so

$(TARGETNAME).so : $(OBJS)
        $(LINK) $(OBJS)  $(LFLAGS) 

.cpp{}.obj :
        $(CXX) $(CFLAGS) $<

.c{}.obj :
        $(CC) $(CFLAGS) $<

clean :
        rm $(OBJS) $(TARGETNAME).so

study1.cpp

#include <stdint.h>

#ifndef WIN32
#define __stdcall
#endif

/*Cで作成された別のファイルにある関数のプロトタイプ宣言*/
extern "C"{
    extern uint32_t nijo(uint32_t a);
    extern uint32_t tasu(uint32_t a,uint32_t b);
}

extern "C" uint32_t __stdcall keisan(uint32_t a,uint32_t b){
    return tasu(nijo(a),b);
}

study1.map

{
  global:
    keisan;
  local: *;
};

で、Makeする。

まずは、うまくいった。

次はテスト用。

study1.cpp

#include <stdio.h>
#include <stdint.h>
#include <dlfcn.h>

typedef uint32_t (*keisan_type)(uint32_t a,uint32_t b);
void* dll;
keisan_type keisan;

int main(int argc,char** argv){
    uint32_t a,b,ans;
    dll=dlopen("./study1.so",RTLD_LAZY);
    keisan=(keisan_type)dlsym(dll,"keisan");
    a=2;
    b=3;
    ans=keisan(a,b);
    printf("%d^2 + %d = %d\n",a,b,ans);
    return 0;
}

で、例によって直でコンパイルして実行する。

うまくいった。