Sharing C functions between two XS Perl modues - c

I have a Perl module A that is a XS based module. I have an A.xs file, and an aux_A.c file, where I have some standard C functions. I use DynaLoader, and it works file.
Now, I have a new module B, that is also a XS module. I also have the B.xs file, and the aux_B.c file. Now, I want that a standard C function defined in aux_B.c file to be able to use a function defined in aux_A.c file.
One option is to make A module to create a standard C library, and link B module with it. But I was trying to get away from that option.
Is there any other way to go?
What I am currently getting is DynaLoader complaining on undefined symbol when trying to load the B.so library.
Thanks
Alberto

To make module A export its C symbols with DynaLoader, you have to add the following to A.pm:
sub dl_load_flags { 1 }
This is badly documented, unfortunately. See this thread on PerlMonks and the DynaLoadersource code for more details. The effect of the flag is to set RTLD_GLOBAL when loading A.so with dlopen which makes its symbols available to other shared objects.

Related

Importing Modules — customized Modules in C

I am currently learning the C programming language and I'm having some issues with importing modules I created.
I created a small module to read with fgets and flush the buffer from stdin perfectly and I don't want to keep writing the code every single time. I just want to import this small module like I used to do in Python. I didn't knew how because I'm not using an IDE. I'm just compiling with gcc in terminal and using a text editor. I tried to search with Google,but in vain.
You should create a header for your module that declares the functions in the module – and any other information that a consumer of the module needs. You might call that header weekly.h, a pun on your name, but you can choose any name you like within reason.
You should create a library (shared or static — that's up to you) that contains the functions (and any global variables, if you're so gauche as to have any) defined by your module. You might call it libweekly.so or libweekly.a — or using the extensions appropriate to your machine (.dylib and .a on macOS, for example). The source files might or might not be weekly.c — if there's more than one function, you'll probably have multiple source files, so they won't all be weekly.c. You should put this code (the header and the source files and their makefile) into a separate source directory.
You should install the header(s) and the library in a well-known location (e.g. $HOME/include for headers and $HOME/lib for the library — or maybe in the corresponding directories under /usr/local), and then ensure that the right options are used when compiling (-I$HOME/include for the headers) or linking (-L$HOME/lib and -lweekly).
Your source code using the module would contain:
#include "weekly.h"
and your code would be available. With shared libraries in $HOME/lib, you would have to ensure that the runtime system knows where to find the library. If you install it in /usr/local, that is done for you already. If you install it in $HOME/lib, you have to investigate things like /etc/ld.so.conf or the LD_LIBRARY_PATH or DYLIB_LIBRARY_PATH environment variables, etc.
You need to create a header file (.h) with your function declarations types and extern variables. Then in the program where you want to use those functions include this .h file and and add the compiled .o file (with your functions) to the object file list. And you are done.

How to generate a hex without main function using IAR linker - xlink?

The point is to generate a hex without main function using IAR linker - xlink?
This code should be loaded into the RAM of RL78 MCU.
A quick Google search of iar generate hex from library brought me to this document, "Creating an Absolutely Placed Library", as a first result. It has all the information you need, plus some information on using a CRC for consistency checking. The document is for the IAR EWRX variant, but the concepts should all be the same.
The basic process is to compile your library as an executable, but without a main() function in it. You'll need to set your library configuration under General -> Library Options to None. You can also setup your file conversion settings at this point.
Since you don't have a main() function for a program entry point, you will need to create an entry function to call the IAR C runtime initialization function, __iar_data_init2(), and then set the linker to use this function as the entry point (which can be found under Linker Options -> Library Options).
When building a library, all the symbols will be preserved until the final link step for the application using it, but since you are building this as an executable, it is important that the symbols you want to keep have the __root keyword, or under Linker -> Extra Options you can specify --no-remove to keep all symbols.
In the next step, you need to use isymexport to export the symbols that you want. You will need a file to direct the tool what to export. In the example, they have a file that just contains the following:
show lib_*
show __checksum*
This will direct the tool to export all symbols beginning with lib_ and all symbols beginning with __checksum. They note that __iar_data_init2() should not be exported, as this would cause conflicts with the application that ultimately will use this code. You invoke the tool like so:
isymexport <path to .out file> <path to output from tool> --edit <path to file created above>
Now you should have the output from isymexport and the library file that you were looking for. For the application using this library, you'll need to add the output from isymexport as a library under Linker -> Library, and in your application, you'll need to call your entry function in the library before you attempt to use any of the library's symbols.
This should be the information you need to generate a library that lives in a hex file and can be loaded separately, as well as how to use that library. The referenced document has a lot more detail, so if it is available at that link (or can be found elsewhere by title) it will be a better reference than my summary here.

Symbols stay local and not exported properly

A colleague gave me a modified version of a shared library where he added a GTK widget.
When inspecting the shared library file I see that the new widget functions are defined as local and not global.
I have tried to set the visibility attribute of GCC on the function (after the declaration itself, before the semicolon), it has G_BEGIN_DECLS around it and the same common headers and defines as other files in the library that are exported properly.
Is there a linker command line option I may be missing? A list of files that "can" export that is used by gcc, perhaps another definition for exported functions?
When inspecting the shared library file I see that the new widget functions are defined as local and not global.
By default, all symbols in a shared library are exported (unless you compile with -fvisibility=hidden or protected.
Since observe that your symbols are LOCAL, it is a good bet that your link command uses a linker version script to control symbol visibility (to hide all symbols except ones that are explicitly exported), and that you have not modified that version script to add your functions to the export list.
Look for -Wl,--version-script=... on your link command line, and modify the version script appropriately.
See also this answer.
I've found out that the library uses a regular expression to filter exports (the -export-symbols-regex switch), adding another regular expression made the symbols properly exported, now I everything is linking properly.

perl syntax check without loading c library

I would like to check syntax of my perl module (as well as for imports), but I don't want to check for dynamic loaded c libraries.
If I do:
perl -c path_to_module
I get:
Can't locate loadable object for module B::Hooks::OP::Check in #INC
because B::Hooks::OP::Check are loading some dynamic c libraries and I don't want to check that...
You can't.
Modules can affect the scripts that use them in many ways, including how they are parsed.
For example, if a module exports
sub f() { }
Then
my $f = f+4;
means
my $f = f() + 4;
But if a it were to export
sub f { }
the same code means
my $f = f(+4);
As such, modules must be loaded to parse the script that loads it. To load a module is simply to execute it, be it written in Perl or C.
That said, some folks put together PPI to address the needs of people like you. It's not perfect —it can't be perfect for the reasons previously stated— but it will give useful results nonetheless.
By the way, the proper way to syntax check a module is
perl -e'use Module;'
Using -c can give errors where non exists and vice-versa.
The syntax checker loads the included libraries because they might be applying changes to the syntax. If you're certain that this is not happening, you could prevent the inclusion by manipulating the loading path and providing a fake b::Hooks::OP::Check.

How to resolve conflicting linker dependencies?

If I have two libraries, A.lib and B.lib, both of which export foo and bar, how do I tell the linker to use the symbol foo from A.lib and the symbol bar from B.lib?
You cannot. For your example you can have definitions from foo.lib or bar.lib but not both (especially if you cannot recompile the libraries and set symbol visibility so that only the symbols you want are exported). The order you link them against your application will depend on which library's definitions are used (you'll have to use the scientific method, I think the first one linked wins). Niklas Hansson's answer is a great way to do this dynamically but it seems you don't want to modify the original application, either, to dynamically pick/choose what symbols to take out of the libraries.
If you really wanted to you could mangle the symbol tables with a hex editor so that the symbols you don't want exported have different names (hacky, but it would work). I know on Linux there is a tool called objcopy that would let you do this (not sure about Windows).
You can use LIB.EXE /EXTRACT ... to extract only the object files you want to use, and link those files into your own application.
Or you may use LIB to create one new library containing the elements you need:
First, use /REMOVE on A.LIB to remove bar.obj:
LIB.EXE /OUT:ANOBAR.LIB /REMOVE:bar.obj A.LIB
Then combine A.LIB and B.LIB, and make sure to use ANOBAR.LIB as the last on the command line to ensure its foo.obj is used instead of B.LIB's:
LIB.EXE /OUT:COMBINED.LIB B.LIB ANOBAR.LIB
Details are found here: Managing a library, especially the paragraph:
You can use LIB [...] To replace a library member with a new object, specify the library containing the member object to be replaced and the file name for the new object (or the library that contains it). When an object that has the same name exists in more than one input file, LIB puts the last object specified in the LIB command into the output library. When you replace a library member, be sure to specify the new object or library after the library that contains the old object.
I didn't test the command lines given, but I've used similar ones extensively in the past.
If you are using dynamic libraries, you could use dynamic loading and pick foo from A and bar from B when loading.

Resources