Recent

Author Topic: como usar uma dll escrito em c  (Read 956 times)

affonso

  • New Member
  • *
  • Posts: 18
como usar uma dll escrito em c
« on: April 10, 2021, 04:51:11 am »
Olá a todos eu estou tentando usar uma simples dll escrito em c no meu programa feito em fpc. Estou usando o opensuse 15.2

este é o código em c.

Code: C  [Select][+][-]
  1. //arquivo dll.c
  2. #include <stdio.h>
  3.  
  4. int dll()
  5. {
  6.     printf("dll()\n");
  7.     return 0;
  8. }

// estou usando o seguinte comando para gerar a dll
//gcc -c dll.c -fpic
//gcc -shared -o libdll.so dll.o

este é o programa feito em fpc

Code: Pascal  [Select][+][-]
  1. program teste;
  2. // Importa função dll
  3. function add(): Integer; cdecl; external 'libdll.so';
  4. begin //main
  5.  add();
  6. end.

Estou usando o comando fpc teste.pas para gerar o programa execultável, mas aparece a seguinte mensagem de erro

Code: Text  [Select][+][-]
  1. Free Pascal Compiler version 3.2.0 [2020/12/18] for x86_64
  2. Copyright (c) 1993-2020 by Florian Klaempfl and others
  3. Target OS: Linux for x86-64
  4. Compiling teste.pas
  5. Linking teste
  6. /usr/bin/ld: teste.o: in function `main':
  7. teste.pas:(.text.n_main+0xa): undefined reference to `add'
  8. teste.pas(11,1) Error: Error while linking
  9. teste.pas(11,1) Fatal: There were 1 errors compiling module, stopping
  10. Fatal: Compilation aborted
  11. Error: /usr/bin/ppcx64 returned an error exitcode

Alguém poderia me ajudar? desde já agradeço.

quando eu comento na linha add(); o programa até compila mas quando eu executo o programa aparece a seguinte msg:
./teste: error while loading shared libraries: libdll.so: cannot open shared object file: No such file or directory


[Editado para adicionar tags de código - consulte Como usar os fóruns]



« Last Edit: April 10, 2021, 09:06:13 am by trev »

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 511
  • Professional amateur ;-P
Re: como usar uma dll escrito em c
« Reply #1 on: April 10, 2021, 05:10:45 am »
Boas Afonso,

Olá a todos eu estou tentando usar uma simples dll escrito em c no meu programa feito em fpc. Estou usando o opensuse 15.2

Recentemente houve alguém que fez a mesma pergunta e foi-lhe dado uma série de respostas.

Como está a tua leitura de Inglês?

Grande abraço,
Gus
Lazarus 2.1.0(trunk) FPC 3.3.1(trunk) Ubuntu 20.10 64b Dark Theme
Lazarus 2.0.12(stable) FPC 3.2.0(stable) Ubuntu 20.10 64b Dark Theme
http://github.com/gcarreno

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 511
  • Professional amateur ;-P
Re: como usar uma dll escrito em c
« Reply #2 on: April 10, 2021, 05:30:22 am »
Boas Afonso,

Não consegui encontrar o thread, mas tenho o zip com o exemplo que foi dado nesse thread.

A dll é criada em Lazarus e não C, mas como usar-la está bem exemplificado.

Infelizmente não te posso ajudar com a parte C das coisas. No entanto, parece-me que não publicas(exports) a funcção add da tua lib. Coisa a ver.

Dá uma olhada no código que ligo a este post.

Grande abraço,
Gus
Lazarus 2.1.0(trunk) FPC 3.3.1(trunk) Ubuntu 20.10 64b Dark Theme
Lazarus 2.0.12(stable) FPC 3.2.0(stable) Ubuntu 20.10 64b Dark Theme
http://github.com/gcarreno

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1441
  • Former Delphi 1-7, 10.2 user
Re: como usar uma dll escrito em c
« Reply #3 on: April 10, 2021, 08:58:51 am »
Escrevi um exemplo em C para o macOS, mas ele deve dar uma ideia (apenas ignore as informações específicas do macOS): Example C Static Library.
Lazarus 2.1 r65061 FPC 3.3.1 r49223 macOS 10.14.6 Xcode 11.3.1
Lazarus 2.1 r65070 FPC 3.3.1 r49223 macOS 11.2.3 aarch64 Xcode 12.4
Lazarus 2.1 r61574 FPC 3.3.1 r42318 FreeBSD 12.1 amd64 VMware VM
Lazarus 2.1 r61574 FPC 3.0.4 Ubuntu 20.04 Parallels VM
Lazarus 2.0.10 FPC 3.2.0 Win10 Parallels VM

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 511
  • Professional amateur ;-P
Re: como usar uma dll escrito em c
« Reply #4 on: April 10, 2021, 01:31:39 pm »
Hey Trev,

Escrevi um exemplo em C para o macOS, mas ele deve dar uma ideia (apenas ignore as informações específicas do macOS): Example C Static Library.

Devo dizer, excelente exemplo!! Muito obrigado.

Mas, se não me engano, o @Afonso queria usar "shared" e não "static".

Tens algum exemplo de "shared"?

Grande abraço,
Gus
Lazarus 2.1.0(trunk) FPC 3.3.1(trunk) Ubuntu 20.10 64b Dark Theme
Lazarus 2.0.12(stable) FPC 3.2.0(stable) Ubuntu 20.10 64b Dark Theme
http://github.com/gcarreno

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1441
  • Former Delphi 1-7, 10.2 user
Re: como usar uma dll escrito em c
« Reply #5 on: April 10, 2021, 01:57:45 pm »
Bibliotecas dinâmicas também são conhecidas como bibliotecas compartilhadas dinâmicas, objetos compartilhados ou bibliotecas vinculadas dinamicamente.
Bibliotecas estáticas também são conhecidas como bibliotecas de arquivo estático e bibliotecas compartilhadas vinculadas estáticas.

Dynamic Library Example.
Lazarus 2.1 r65061 FPC 3.3.1 r49223 macOS 10.14.6 Xcode 11.3.1
Lazarus 2.1 r65070 FPC 3.3.1 r49223 macOS 11.2.3 aarch64 Xcode 12.4
Lazarus 2.1 r61574 FPC 3.3.1 r42318 FreeBSD 12.1 amd64 VMware VM
Lazarus 2.1 r61574 FPC 3.0.4 Ubuntu 20.04 Parallels VM
Lazarus 2.0.10 FPC 3.2.0 Win10 Parallels VM

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 511
  • Professional amateur ;-P
Re: como usar uma dll escrito em c
« Reply #6 on: April 10, 2021, 02:17:02 pm »
Oies Trev,

Bibliotecas dinâmicas também são conhecidas como bibliotecas compartilhadas dinâmicas, objetos compartilhados ou bibliotecas vinculadas dinamicamente.
Bibliotecas estáticas também são conhecidas como bibliotecas de arquivo estático e bibliotecas compartilhadas vinculadas estáticas.

É deveras desconcertante saber que és Australiano e que me estás a corrigir na minha língua nativa, LOL!!
No entanto tenho de admitir que por preguiça não fui à procure da tradução para Português de "shared" e "static".
Mas agora que abordas o assunto, lembro-me que no meu tempo se dizia: livraria/biblioteca partilhada "shared" ou livraria/biblioteca estática "static"
Não tinha-mos tanta propensão a essa verbosidade :)

Dynamic Library Example.

Bom exemplo da parte do Lazarus. Falta a parte de C ?
Mas no entanto este é um fórum sobre Lazarus, né? :)

Grande abraço,
Gus
Lazarus 2.1.0(trunk) FPC 3.3.1(trunk) Ubuntu 20.10 64b Dark Theme
Lazarus 2.0.12(stable) FPC 3.2.0(stable) Ubuntu 20.10 64b Dark Theme
http://github.com/gcarreno

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1441
  • Former Delphi 1-7, 10.2 user
Re: como usar uma dll escrito em c
« Reply #7 on: April 10, 2021, 02:25:41 pm »
Bom exemplo da parte do Lazarus. Falta a parte de C ?

Não - {$linklib C} = Biblioteca C dinâmica do macOS fornecida pelo sistema operacional.

Meu português é cortesia do Google translate :)
Lazarus 2.1 r65061 FPC 3.3.1 r49223 macOS 10.14.6 Xcode 11.3.1
Lazarus 2.1 r65070 FPC 3.3.1 r49223 macOS 11.2.3 aarch64 Xcode 12.4
Lazarus 2.1 r61574 FPC 3.3.1 r42318 FreeBSD 12.1 amd64 VMware VM
Lazarus 2.1 r61574 FPC 3.0.4 Ubuntu 20.04 Parallels VM
Lazarus 2.0.10 FPC 3.2.0 Win10 Parallels VM

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 511
  • Professional amateur ;-P
Re: como usar uma dll escrito em c
« Reply #8 on: April 10, 2021, 03:06:27 pm »
Hey Trev,

Não - {$linklib C} = Biblioteca C dinâmica do macOS fornecida pelo sistema operacional.

Estás correto em dizer que linkaste com uma biblioteca que existe.
Mas no primeiro exemplo, o estático, forneceste código em C para a biblioteca.
Neste exemplo, o dinâmico, não forneceste código em C. Capiche, mio amore?

Meu português é cortesia do Google translate :)

DUH :D
O que eu acho ainda mais divertido é que o teu Português é do Brasil e o meu é de Portugal.
Tirei as minhas dúvidas de qual o Google Translate usa com: "Sistema Operacional - pt_BR" "Sistema Operativo - pt_PT" ;)

Grande abraço,
Gus
Lazarus 2.1.0(trunk) FPC 3.3.1(trunk) Ubuntu 20.10 64b Dark Theme
Lazarus 2.0.12(stable) FPC 3.2.0(stable) Ubuntu 20.10 64b Dark Theme
http://github.com/gcarreno

affonso

  • New Member
  • *
  • Posts: 18
Re: como usar uma dll escrito em c
« Reply #9 on: April 11, 2021, 06:19:59 pm »
Fico muito feliz pelas respostas essa comunidade é muito boa. Eu não sou um programador profissional, apenas é um hobby que eu tenho. Então o que eu to fazendo não é nada importante.

Eu consigo criar uma DLL e usar no Freepascal e até conseguir realizar o inline em código c com sucesso. Seguindo esse tutorial ftp://ftp.freepascal.org/fpc/docs-pdf/CinFreePascal.pdf

Eu fiz uma DLL simples no Freepascal para ser usado na linguagem Dlang exemplo

Code: Pascal  [Select][+][-]
  1. // referência https://www.freepascal.org/docs-html/prog/progse55.html
  2. //arquivo subs.pas
  3. library subs;
  4. procedure SubStr(); cdecl;
  5. begin
  6.   write('hello World');
  7. end;
  8. exports
  9.   SubStr;
  10. end.
  11.  

Code: Pascal  [Select][+][-]
  1. // referência https://dlang.org/articles/dll-linux.html
  2. //arquivo Gethello.d
  3. import core.stdc.stdio;
  4. import core.stdc.stdlib;
  5. import core.sys.posix.dlfcn;
  6.  
  7. extern (C) int SubStr();
  8. int main()
  9. {
  10.     printf("+main()\n");
  11.     void* lh = dlopen("libsubs.so", RTLD_LAZY);
  12.     if (!lh)
  13.     {
  14.         fprintf(stderr, "dlopen error: %s\n", dlerror());
  15.         exit(1);
  16.     }
  17.     printf("libsubs.so is loaded\n");
  18.     int function() fn = cast(int function())dlsym(lh, "SubStr");
  19.     char* error = dlerror();
  20.     if (error)
  21.     {
  22.         fprintf(stderr, "dlsym error: %s\n", error);
  23.         exit(1);
  24.     }
  25.     printf("dll() function is found\n");
  26.     fn();
  27.     printf("unloading libsubs.so\n");
  28.     dlclose(lh);
  29.     printf("-main()\n");
  30.     return 0;
  31. }
  32.  

comandos para compilar

fpc subs.pas
dmd Gethello.d
dmd Gethello.o  -defaultlib=libphobos2.so -L-rpath=/home/affonso/Desktop/lab7

Esse exemplo acima funciona perfeitamente, porém quando eu tento fazer o inverso de criar uma DLL em Dlang e importar a DLL no código FPC ele compila o programa roda só que a função não aparece o valor. Exemplo

Code: Pascal  [Select][+][-]
  1. //referência https://dlang.org/articles/dll-linux.html
  2. //arquivo dll.d
  3. import core.stdc.stdio;
  4. extern (C) int dll(int b)
  5. {      
  6.         int a = 10;
  7.         int c = a * b;
  8.         return c;
  9. }
  10.  

Code: Pascal  [Select][+][-]
  1. //referência https://www.freepascal.org/docs-html/prog/progse56.html
  2. // arquivo teste.pas
  3. program teste;
  4. uses dynlibs;
  5. type
  6.         TSubStrFunc = function(a: Integer) :Integer; cdecl; external;
  7. const
  8.         baselibname = 'libdll.';
  9. {$ifdef windows}
  10.         libext = 'dll';
  11. {$else}
  12. {$ifdef macos}
  13.         libext = 'dylib';
  14. {$else}
  15.         libext = 'so';
  16. {$endif}
  17. {$endif}
  18. var
  19.         lib:    TLibHandle;
  20.         dll:    TSubStrFunc;
  21.         a:              Integer;
  22. begin   a:=10;
  23.         lib:=LoadLibrary('libdll.so');
  24.         Pointer(dll):=GetProcAddress(lib,'dll');
  25.         writeLn(dll(a));
  26.         unloadLibrary(lib);
  27. end.
  28.  

Comandos para compilar

dmd -c dll.d -fPIC
dmd -oflibdll.so dll.o -shared -defaultlib=libphobos2.so -L-rpath=/home/affonso/Desktop/lab7
fpc teste.pas

O que há de errado com o programa teste.pas que não imprime a função da DLL como descrito na linha writeLn(dll(a));????

Desculpa pelo texto enorme mas eu queria descrever com o máximo de detalhe.

respondendo as perguntas acima meu inglês é péssimo e tenho que estudar isso. E eu queria algo como Library Shared. Em modo static eu até consigo fazer e por isso eu tô tentando no modo Library Shared.


 

TinyPortal © 2005-2018