2023年12月29日金曜日

WSLでLinuxのDLL作成

 

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

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

Makefile_Lin
  1. TARGETNAME=study1
  2. CC=gcc
  3. CXX=g++
  4. LINK=gcc
  5. CFLAGS= -fPIC -O4 -Wall -c
  6. LFLAGS= -shared -static-libgcc -static-libstdc++ -Wl,--version-script,$(TARGETNAME).map -o $(TARGETNAME).so
  7. #LFLAGS= -shared -Wl,--version-script,$(TARGETNAME).map -o $(TARGETNAME).so
  8. OBJS= $(TARGETNAME).o nijo.o tasu.o
  9.  
  10. ALL : $(TARGETNAME).so
  11.  
  12. $(TARGETNAME).so : $(OBJS)
  13. $(LINK) $(OBJS) $(LFLAGS)
  14.  
  15. .cpp{}.obj :
  16. $(CXX) $(CFLAGS) $<
  17.  
  18. .c{}.obj :
  19. $(CC) $(CFLAGS) $<
  20.  
  21. clean :
  22. rm $(OBJS) $(TARGETNAME).so

study1.cpp

  1. #include <stdint.h>
  2.  
  3. #ifndef WIN32
  4. #define __stdcall
  5. #endif
  6.  
  7. /*Cで作成された別のファイルにある関数のプロトタイプ宣言*/
  8. extern "C"{
  9. extern uint32_t nijo(uint32_t a);
  10. extern uint32_t tasu(uint32_t a,uint32_t b);
  11. }
  12.  
  13. extern "C" uint32_t __stdcall keisan(uint32_t a,uint32_t b){
  14. return tasu(nijo(a),b);
  15. }

study1.map

  1. {
  2. global:
  3. keisan;
  4. local: *;
  5. };

で、Makeする。

まずは、うまくいった。

次はテスト用。

study1.cpp

  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <dlfcn.h>
  4.  
  5. typedef uint32_t (*keisan_type)(uint32_t a,uint32_t b);
  6. void* dll;
  7. keisan_type keisan;
  8.  
  9. int main(int argc,char** argv){
  10. uint32_t a,b,ans;
  11. dll=dlopen("./study1.so",RTLD_LAZY);
  12. keisan=(keisan_type)dlsym(dll,"keisan");
  13. a=2;
  14. b=3;
  15. ans=keisan(a,b);
  16. printf("%d^2 + %d = %d\n",a,b,ans);
  17. return 0;
  18. }

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

うまくいった。


0 件のコメント:

コメントを投稿