Recent

Author Topic: como usar uma dll escrito em c  (Read 4596 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: 1111
  • 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 3.99(main) FPC 3.3.1(main) Ubuntu 23.10 64b Dark Theme
Lazarus 3.0.0(stable) FPC 3.2.2(stable) Ubuntu 23.10 64b Dark Theme
http://github.com/gcarreno

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1111
  • 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 3.99(main) FPC 3.3.1(main) Ubuntu 23.10 64b Dark Theme
Lazarus 3.0.0(stable) FPC 3.2.2(stable) Ubuntu 23.10 64b Dark Theme
http://github.com/gcarreno

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2020
  • 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.

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1111
  • 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 3.99(main) FPC 3.3.1(main) Ubuntu 23.10 64b Dark Theme
Lazarus 3.0.0(stable) FPC 3.2.2(stable) Ubuntu 23.10 64b Dark Theme
http://github.com/gcarreno

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2020
  • 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.

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1111
  • 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 3.99(main) FPC 3.3.1(main) Ubuntu 23.10 64b Dark Theme
Lazarus 3.0.0(stable) FPC 3.2.2(stable) Ubuntu 23.10 64b Dark Theme
http://github.com/gcarreno

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2020
  • 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 :)

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1111
  • 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 3.99(main) FPC 3.3.1(main) Ubuntu 23.10 64b Dark Theme
Lazarus 3.0.0(stable) FPC 3.2.2(stable) Ubuntu 23.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