Hi,
I'm trying to make an interface to a kind of library, but I'm stuck. Any pointers are welcome.
There is a C-header file, but this is common for a number of C-modules. If I translate (h2pas) this file, and use it, the linker tries to find an o-file, which does not exist. Any suggestions how to handle this ? TIA,
Koenraad Lelong.
P.S. I'm trying to interface to the 1-wire routines for Linux of Dallas Semiconductors. Did anyone see any "ports" ? I googled, but found nothing.
Mailing lists / fpc-pascal / 2005-03
Help needed with interfacing to C-object-files.
27 messages · 9 people · –
- KKoenraad Lelong 12
- MMarc Santhoff 5
- JJeff Pohlmeyer 4
- AAlain Michaud 1
- FFlorian Klaempfl 1
- JJonas Maebe 1
- +3 more
Reply by email Subscribe to this list Your subscription
Read-only archive. Use j and k to move between messages.
Show quoted text 6 lines
You've got to compile the C files to .o (gcc -c thesource.c) and then link them into your pascal unit ({$L thesource.o}). This way it should work, I'm using some C stuff like that.
HTH,
Marc
Marc Santhoff wrote 16 lines
Let me explain more : the header file is used in at least five source-files, so compiling gives (at least) five .o files, but none with the name of the header-file.
I was thinking that splitting that header-file in smaller files, each for its own source could do the trick, but I'll have to check this carefully. I had hoped for another suggestion.
Anyway, thanks for the response.
Koenraad.
Koenraad Lelong wrote 10 lines
You can simply change the resulting pascal file so it has the correct {$o } statements ? h2pas does not know (and can not know) what the names of the object files are. C does not work like that.
Michael.
Let me explain more : the header file is used in at least five source-files, so compiling…
Show quoted text 24 lines
Hm, I don't know, how the translated header looks in pascal, but if it's a complete unit itself you could try to {$L xxx} all resulting .o files in that unit. So any declared function and type should be found ... the other thing would be, if the sources from the 1-wire stuff form a dynamic library, then you simply have to tell the linker to pull this lib (.so) in
fpc -k-l<thelibraryname without the.so-ending> ...
should work and does for me, too. Or it needs an additional "-k-L/the/path/to/1-wire-lib". The only thing in your sources is to put the translated header in the uses clause.
HTH,
Marc
Let me explain more : the header file is used in at least five source-files, so compiling gives (at least) five .o files, but none with the name of the header-file.
From the command line :
ar -r libDallas.a file1.o file2.o ...
and then, in your program:
{$LINKLIB Dallas}- Jeff
Hm, I don't know, how the translated header looks in pascal, but if it's a complete unit…
Marc Santhoff wrote 47 lines
I put some files on http://users.edpnet.be/~koenraad. ulinuxgnu300.zip is the original file from DallasSemiconductor, with the c-sources.
ownet.h.tar.gz contains the "problem" header file, in C en "raw" h2pas, and two other header files used by temp.c, with their h2pas counterparts, and finally the temp.c-file which I'm trying to implement is FPC, as a testcase.
Finally temp1.pas.tar.gz contains my FPC-versions of the header-files, cleaned up somewhat, so I could successfully compile. Of course this needs more work to make it usefull.
If I compile without an o-path (-Fo), findtype.o and temp10.o are not found and of course ownet.o. If I add a path to the files findtype.o and temp10.o only ownet.o is not found, because it does not exist. Let me say that I'm new to programming for Linux, and to programming with FPC. I do use Delphi at work, so I know something of Pascal, although I'm not an expert.
Thanks for any help,
Koenraad.
Hm, I don't know, how the translated header looks in pascal, but if it's a complete unit…
Marc Santhoff wrote 52 lines
I should appologise. I don't know how it happened, maybe sand in my eyes ;-), but I seem to have misread the output. It wasn't ownet.o it didn't find, but ownetu.o. When I saw this I realised there had to be something wrong about my linking string. And indeed it was. After correcting this linking went fine, except for a huge number of errors. After including more o-files in ownet.pp, these were resolved.
Now I have only about 10 errors, in the main program. I'm working to resolve these.
What I did want to ask is this : I mentioned adding more o-files in ownet.pp. The files I had to add are used in the first o-files I included, e.g. in ownetu.c ds2480.h/ds2480.c are used, so when I included {$L ds2480.o} in ownet.pp the errors of ownetu disappeared. My question : is the linker not smart enough to find out by itself where to look for those missing object files ?
Is there a way I can avoid this ?
I hope I'm not making a fool of myself any more than I did already ;-). Thanks,
Koenraad.
My question : is the linker not smart enough to find out by itself where to look for those missing object files ?
Not sure if I understand your question, but as Marc already mentioned, you can control this with the -k-L compiler switch.
You can also control the way the compiler/linker searches for various things using directives, eg:
{$OBJECTPATH path}
{$LIBRARYPATH path}
{$UNITPATH path}- Jeff
Show quoted text 12 lines
Hardcoding paths in the source is not advised though, same for Delphi style uses xxxx in '../../othername.pas'; like syntax.
Better solve it outside the source (makefile/batchfile/lazarus project file)
Not sure if I understand your question, but as Marc already mentioned, you can control…
Jeff Pohlmeyer wrote 17 lines
OK, maybe you need more information. This is how I compile : ppc386 -g -Sd -Fo/home/koenraad/owpd300 temp1
My program temp1 'uses' ownet.
In ownet.pp there are a number of routines that are in c-object files. I include these object files with :
{$L owerr.o}
{$L ownetu.o}
etc.
If I compile this I get errors about not finding things used in ownetu.o, e.g. (exact quote) :
/home/koenraad/owpd300/ownetu.o(.text+0xea): In function 'owNext': : undefined reference to 'UMode'
etc.
If I look in ownetu.c I see :
#include "ownet.h"
#include "ds2480.h"
So I added in ownet.pp :
{$L ds2480.o}
then the errors about ownetu.o are gone. Likewise I have to add several other object files not directly used in ownet.pp, but used in files that are linked with {$L...}.
All those object files are in /home/koenraad/owpd300. I assumed that when a routine uses some code in an object file which in turn uses code in another object file, the linker would be smart enough to know to look for that second object file. Of course, if those object files are not in the search-path they will not be found. Actually, when I add -va to the compile command, I see that the compiler searches in a number of paths for code that is used. Why doesn't the linker do the same ? My first tought would even be that I do not have to add those first {$L...}'s.
Maybe these questions have nothing to do with fpc, but I'm trying to understand, so I don't make these errors in the future. If this is explained somewhere, do please give me some pointers. Maybe I'm too used to using Delphi, where such things are hidden from the developper.
Regards,
Koenraad.
Not sure if I understand your question, but as Marc already mentioned, you can control…
Jeff Pohlmeyer wrote 19 lines
OK, maybe you need more information. This is how I compile : ppc386 -g -Sd -Fo/home/koenraad/owpd300 temp1
My program temp1 'uses' ownet.
In ownet.pp there are a number of routines that are in c-object files. I include these object files with :
{$L owerr.o}
{$L ownetu.o}
etc.
If I compile this I get errors about not finding things used in ownetu.o, e.g. (exact quote) :
/home/koenraad/owpd300/ownetu.o(.text+0xea): In function 'owNext': : undefined reference to 'UMode'
etc.
If I look in ownetu.c I see :
#include "ownet.h"
#include "ds2480.h"
So I added in ownet.pp :
{$L ds2480.o}
then the errors about ownetu.o are gone. Likewise I have to add several other object files not directly used in ownet.pp, but used in files that are linked with {$L...}.
All those object files are in /home/koenraad/owpd300. I assumed that when a routine uses some code in an object file which in turn uses code in another object file, the linker would be smart enough to know to look for that second object file. Of course, if those object files are not in the search-path they will not be found. Actually, when I add -va to the compile command, I see that the compiler searches in a number of paths for code that is used. Why doesn't the linker do the same ? My first tought would even be that I do not have to add those first {$L...}'s.
Maybe these questions have nothing to do with fpc, but I'm trying to understand, so I don't make these errors in the future. If this is explained somewhere, do please give me some pointers. Maybe I'm too used to using Delphi, where such things are hidden from the developper.
Regards,
Koenraad.
Koenraad Lelong wroteI assumed that when a routine uses some code in an object file which in turn uses code in another object file, the linker would be smart enough to know to look for that second object file.
No, the linker cannot know in which other object these routines are.
Jonas
OK, maybe you need more information. This is how I compile : ppc386 -g -Sd…
Show quoted text 50 lines
Since I have not enough knowledge about the linkers inner details and about fpc's usage of it I can only advise you to have a look at the original Makefile of the object files in question. The line and variables envolved in linking the 1-wire files should give you some hints on their dependencies.
If anything else fails you could translate the included headers ("ds2480.h" in this case) too and add them to the uses clause ...
Maybe these questions have nothing to do with fpc, but I'm trying to understand, so I don't make these errors in the future. If this is explained somewhere, do please give me some pointers.
I think you should read the man page of the linker.
Maybe I'm too used to using Delphi, where such things are hidden from the developper.
That's the nice part of Delphi. :)
HTH,
Marc
I still don't understand what sort of c "package" you have that generates a bunch of object files, but doesn't create a shared library or static archive.
Does it have its own makefile or configure script? Sometimes adding --enable-shared or --enable-static to configure will tell it to build a library.
> Maybe I'm too used to using Delphi, where such things > are hidden from the developper. That's the nice part of Delphi.
You are talking about searching the system for object files generated by another compiler and automatically linking them into an executable ?
I didn't know Delphi could do that ;-)
- Jeff
Am So, den 13.03.2005 schrieb Jeff Pohlmeyer um 00:03: [..]
Show quoted text 8 lines
No, it doesn't (you know that). But it does free you from thinking about makefiles or the like in building. Very comfortable but not sufficient in any case...
I didn't know Delphi could do that ;-)
In theory any programming language can do anything ... give it some arms, legs and the way to the refrigerator and it'll fetch you another beer. ;)
Cheers,
Marc
I still don't understand what sort of c "package" you have that generates a bunch of…
Jeff Pohlmeyer wrote 8 lines
If you want to take a look, I've put it on
http://users.edpnet.be/~koenraad/www
Since I have no experience with C, I'm having those difficulties. Bye,
Koenraad.
Hi,
I see many messages about linking libraries that were written in C language. I do it at run time. This message is for those that are not so familiar with linux system programming. Here is an exampe:
Supose that I want to use the the function "ibdev" in the module "libgpib.so". From the file "libgpib.h" I could learn more about procedure parameters. Then I found the coresponding types in pascal and wrote my own pascal program:
...
uses libc;
...
type
Tibdev =
function(board_index,pad,sad,timeout,send_eoi,eoi:smallint):smallint;cdecl;
...
var
HandleLIBGPIB : pointer;
ibdev : Tibdev;
...
const
GPIBLIBRARYNAME : pchar = '/usr/local/lib/libgpib.so';
...
begin
...
HandleLIBGPIB := dlopen(GPIBLIBRARYNAME,RTLD_NOW);
if (HandleLIBGPIB = nil) then
begin
showmessage('Library file not found: '+GPIBLIBRARYNAME);
exit;
end;
...
ibdev := Tibdev(dlsym(HandleLIBGPIB,'ibdev'));
if @ibdev = nil then exit;
...Then the procedure "ibdev" can be used normally. I think that:
1 - It is easy to check and take action if the library is not loaded, properly. My program is more robust.
2 - I find that it is not easy to understand the "C" types sometimes. This "dynamic" techniqe can be used to test and debug all the procedures one by one. Also you can declare only the procedures that you will be using, and not bother about the ones that you do not understand.
I hope that this can be usefull. Thank you
Alain Michaud
amiso
rubidium
If you want to take a look, I've put it on http://users.edpnet.be/~koenraad/www
Okay, try this...
In your ulinuxgnu300 directory, type:
make clean
make linux
ar -r libonewire.a *.o
ranlib libonewire.a
And then move the resulting "libonewire.a" file into a directory where the linker can find it, either the directory where your pascal project is, or a system directory like /usr/local/lib/
Then add this one line to your header translation:
{$LINKLIB onewire}Now you should be able to remove all those other {$O} and {$L} things.
Here is my *untested* translation of the headers,
all crammed into one unit:
http://www.geocities.com/yetanothergeek/onewire.pas
I don't have the time+software+hardware to test the results completely, but this should at least let you compile and link.
I still have no idea what this thing is supposed to do - Maybe it is something to fetch that beer Marc was talking about?
HTH,
- Jeff
Jeff Pohlmeyer wrote 43 lines
Okay, try this... In your ulinuxgnu300 directory, type: make clean make linux ar -r…
Jeff Pohlmeyer wrote 40 lines
About the beer, it's pretty close.
1-wire devices are devices like termometers, AD-converters and other devices that can be accessed over 1-wire (actually two : gnd). And I would like to use these thermometer-devices with my Zaurus PDA to measure tempratures of my brewing sessions : I make my own beer. I still have to fetch it myself though ;-).
I'm going to try your unit, but how did you do this ? You must have worked for hours to make that "header" file. Thank you very, very much !
Koenraad.
Koenraad Lelong wroteJeff Pohlmeyer wrote:
...
Show quoted text 14 lines
I'm trying this and it seems to work, partly.
I wrote a clone in fpc of the temp-program, and encountered some strange things.
The library successfully detects the interface, and one device (only one connected at the time). But when the serialnumber of the device is written with the library-function, this does not work. I wrote a routine in fpc to write 8 bytes (=serialnumber) to the screen in hex, and then the serialnumber of the connected device is written on the screen. So the communication-part seems to work.
What I did see is that after I stop the application there is extra text on the screen. This contains the serialnumber of the device. When I comment out the library-calls to write the serialnumber, this is gone. Is it possible that fpc 'monopolises' the standard output, and after the program terminates, the text, written with c-routines while the program was running, finally apears on the screen ?
Second question : are c-double types and fpc-double types compatible ? Last question to Jeff Pohlmeyer : could you explain how you made that unit ? Did you convert all h-files with h2pas, and merged them ? I ask this because that 'library' deals with serial devices (ttyS*). I have a similar one, for USB-devices. I would like to make a unit for this also.
Thanks,
Koenraad.
Koenraad Lelong wrote 5 lines
...
Second question : are c-double types and fpc-double types compatible ?
This must be : c-float and fpc-double.
Sorry for that.
Koenraad.
... I'm trying this and it seems to work, partly. I wrote a clone in fpc of the…
Koenraad Lelong wroteSecond question : are c-double types and fpc-double types compatible ?
I think so. Perhaps cfloat and cdouble should be added to the ctypes unit?
Nikolay Nikolov wrote 6 lines
Already in the cvs.
... I'm trying this and it seems to work, partly. I wrote a clone in fpc of the…
Koenraad Lelong wroteKoenraad Lelong wrote: > Jeff Pohlmeyer wrote:
...
Show quoted text 28 lines
I'm trying to debug this problem. I installed gdb, and ddd. But I can only debug the fpc-program. Can't go into the c-code (I compiled this with -ggdb).
Has anyone experience with this ? Any suggestons ? TIA,
Koenraad.
I put some files on http://users.edpnet.be/~koenraad. ulinuxgnu300.zip is the original…
Am Mi, den 09.03.2005 schrieb Koenraad Lelong um 22:27: [...]
I have been offline for the weekend and monday morning this mail from the 9th of march arrived in my inbox!?
Is it:
1. a problem with the fpc mailing list?
2. a problem with my email provider?
TIA,
Marc
