Login
Username:

Password:

Remember me



Lost Password?

Register now!

Sections

Who's Online
148 user(s) are online (130 user(s) are browsing Forums)

Members: 0
Guests: 148

more...

Support us!

Headlines

 
  Register To Post  

library auto init code
Just popping in
Just popping in


See User information
Hi all

I'm trying to write a library that is able to be opened automatically by other programs using the -lauto flag when compiling them and I'm running into problems. It must be missing something out, but I'm stuck!

I took the example at http://wiki.amigaos.net/wiki/How_to_create_an_AmigaOS_4_library and built the subsequent sample.library. I noticed that idltool created two auto-init source files, autoinit_sample_base.c and autoinit_sample_main.c which weren't being referenced in the generated makefile. So I added them to the makefile sources and built the library.

I then used the following test program based upon the test program in the article. If you run it without any command line args, it will explicitly open the sample library and its interface. If you specify a command line arg, I thought that it should use the auto-init code. I compiled the program using

gcc test.c -o test -lauto -gstabs -I../include

However if I try to run it using the auto-init code, ISample is never initialised. My question is what am I doing wrong?

An archive containing all of the files is at https://www.dropbox.com/s/sy130r5aorl26op/sample.lha?dl=0 and the code for test.c is below

#include <proto/exec.h>
#include <proto/sample.h>
 
#include <stdio.h>
 
int main(int argcchar *argv[])
{
  
myInt val1val2res;
 
  
struct Library *SampleBase NULL;
  
struct SampleIFace *ISample NULL;
 
  
/*
    If no command line args are apssed in, explicitly open the library.
    If any command line args are passed in, then try to use auto init.
  */
  
if (argc == 1)
    {
      
SampleBase = (struct Library *)IExec->OpenLibrary("sample.library"0);
      if(!
SampleBase)
        {
          return -
1;
        }
    
       
ISample = (struct SampleIFace *)IExec->GetInterface(SampleBase"main"1NULL);
       if(!
ISample)
        {
          
IExec->CloseLibrary(SampleBase);
          return -
2;
        }
    }
 
  
val1 123;
  
val2 321;
 
  if (
ISample)
    {
      
res ISample->Addition(val1val2);
      
printf("%ld + %ld = %ld\n"val1val2res);
    }
  else
    {
      
printf ("Error: ISample has not been opened\n");
    }
 
  if (
argc == 1)
    {
      
IExec->DropInterface((struct Interface *)ISample);
      
IExec->CloseLibrary(SampleBase);
    }
 
  return 
0;
}



cheers

Billy

Go to top
Re: library auto init code
Amigans Defender
Amigans Defender


See User information
@billyfish

I think you have to build them as a separate (static link) library, and then reference them on the command line, -lsampleauto or whatever.

Actually I thought the idltool makefile had a section in it to build this.

Go to top
Re: library auto init code
Just can't stay away
Just can't stay away


See User information
@billyfish

You're not supposed to link the files to your library. They will do nothing for you there.

Instead you compile them into a static library:

gcc -O2 -Wall -c -o autoinit_sample_base.o
gcc -O2 -Wall -c -o autoinit_sample_main.o
ar -crv -o libsample_auto.a autoinit_sample_base.o autoinit_sample_main.o

If you copy this file to SDK:locale/newlib/lib you can then link it to your program with "-lsample_auto".

Go to top
Re: library auto init code
Just popping in
Just popping in


See User information
@salass00 and @chris

Thanks chaps that makes total sense. I was getting thrown by the constructor (".zzzz") bit and whether that that was doing something special when the shared library was being opened.

Go to top
Re: library auto init code
Home away from home
Home away from home


See User information
@salass00

Is there any trick to getting this to work? I've tried what you suggest, but it's still not opening the library automatically.

EDIT: Or, does the autoinit code generated by IDLTool no longer work with newer versions of GCC? If so, how do we fix it?

Hans


Edited by Hans on 2019/4/11 14:30:36
Join Kea Campus' Amiga Corner and support Amiga content creation
https://keasigmadelta.com/ - see more of my work
Go to top
Re: library auto init code
Just can't stay away
Just can't stay away


See User information
@Hans
If you are using the sample code provided in billyfish's original post, the test.c code is defective. The autoinit code will assign values to SampleBase and ISample. His test code then assigns NULL to those variables which makes it look like the autoinit isn't working.

I compiled the the library and test code with the current public SDK and it worked. If libsample_auto is in SDK:newlib/lib/ and sample.library is in LIBS: then the autoinit works when a valid test program is compiled with something like: gcc test.c -lsample_auto -o test


Edited by xenic on 2019/4/11 17:53:32
Amiga X1000 with 2GB memory & OS 4.1FE + Radeon HD 5450

Go to top
Re: library auto init code
Just can't stay away
Just can't stay away


See User information
@Hans

Include the relevant <proto/#?.h> to get the extern definitions of the library base and interface globals.

Make sure that you don't define variables with the same name yourself (like billyfish does) and that you don't define __NOLIBBASE__ or __NOGLOBALIFACE__.

If you follow the above then any use of the library interface like "ISomeLib->SomeFunc(blah)" should cause the relevant interface constructor to be used.

You also need to be using standard startup code for it to work.

Go to top
Re: library auto init code
Home away from home
Home away from home


See User information
@salass00

It's my own code, and I'm only using __USE_INLINE__. It's definitely linking the static library, because objdump lists the lib's .ctors and .dtors. Added to that, it won't build if I don't link to the autoinit stub library, and it'll complain about the missing interface pointer.

However, I get a NULL pointer crash at the first function call for the library, which means that the code is never run.

EDIT: Of course, I am using the standard startup code, yet it's simply not being run.

EDIT2: As an experiment, I tried using a graphics library function, and the official libauto's code *does* get called. Objdump shows the graphics library's entries in .ctors and .dtors, along with those for my library. So why are only the graphics library's ones called?

Hans


Edited by Hans on 2019/4/12 1:57:11
Edited by Hans on 2019/4/12 2:05:11
Join Kea Campus' Amiga Corner and support Amiga content creation
https://keasigmadelta.com/ - see more of my work
Go to top
Re: library auto init code (solved)
Home away from home
Home away from home


See User information
@Hans

As it turns out, the autoinit code was being called, but it was silently failing.

BE WARNED, assert() seems to do nothing. So, if your library's autoinit stubs rely on assert() for error handling then I highly recommend you change it, because it will fail silently. Better print an error using IDOS->PutErrStr() (or pop up an info requester) and then call abort().

Hans

Join Kea Campus' Amiga Corner and support Amiga content creation
https://keasigmadelta.com/ - see more of my work
Go to top
Re: library auto init code (solved)
Just popping in
Just popping in


See User information
I'm revisiting this code as I'm about to release a new version of the library code generation project that this was all part of as well as open sourcing it.

I'll check the code with the assert () calls in, I think I just refactored the code the generated by IDLTool, but I could be wrong.

Go to top
Re: library auto init code (solved)
Just can't stay away
Just can't stay away


See User information
@Hans
Strange that the assert() doesn't work. When I D/L billyfish's sample code, modified the test program, compiled everything and tested it the function worked. When I removed the sample.library from LIBS: and ran the test program, I got an error on the command line that was produced by the autoinit assert() for the library base being NULL. Maybe some further investigation of assert() might be helpful.


Edited by xenic on 2019/4/14 19:22:12
Amiga X1000 with 2GB memory & OS 4.1FE + Radeon HD 5450

Go to top
Re: library auto init code (solved)
Just can't stay away
Just can't stay away


See User information
@Hans

Did you define NDEBUG when compiling the autoinit code? If so assert() would be defined as a no-op.

Other than that I can't see why assert() wouldn't be working.

Go to top
Re: library auto init code (solved)
Home away from home
Home away from home


See User information
@salass00

Quote:
Did you define NDEBUG when compiling the autoinit code? If so assert() would be defined as a no-op.

No. It's very strange that it did nothing for me, but it works for xenic.

I personally think that assert() shouldn't be used for autoinit code even if it works, because an error message saying "Couldn't open sample.library" is much clearer than an assertion failure message.

Ideally it would open an error requester, but even IDOS->PutErrorStr() makes it clear why it's failing.

Hans

Join Kea Campus' Amiga Corner and support Amiga content creation
https://keasigmadelta.com/ - see more of my work
Go to top

  Register To Post

 




Currently Active Users Viewing This Thread: 1 ( 0 members and 1 Anonymous Users )




Powered by XOOPS 2.0 © 2001-2024 The XOOPS Project