I have two libraries, I want to call routines in the first library, they then call routines in the second library, but crash because those symbols are undefined. Is it possible to say "load these symbols" from library XX even though I don't want to call them?
testlib1.c:
#include <stdio.h>
void sub2();
void sub1() {
printf("Called sub1\n");
sub2();
}
testlib2.c:
#include <stdio.h>
void sub2() {
printf("Called sub2\n");
}
testit.p6:
use NativeCall;
sub sub1() is native('testlib1') {}
sub sub2() is native('testlib2') {}
sub1();
error:
Cannot locate native library 'libtestlib1.so': ./libtestlib1.so: undefined symbol: sub2
If I call sub2 manually before calling sub1, it works fine, but I don't want to do that..
Ok, This makes it work, but is a non-portable workaround -- it only works if your MoarVM is built with dyncall. It seems like there should be some exposed function to NativeCall world that does this portably.
use NativeCall;
sub dlLoadLibrary(Str --> Pointer) is native {}
dlLoadLibrary('libtestlib2.so');
sub sub1() is native('testlib1') {}
sub1();
dlLoadLibrary is the dyncall way to load a dynamic library, which is apparently enough for the symbol to be resolved.
Better suggestion from #jnthn:
sub fake() is native('testlib2');
try fake();
fake() loads testlib2, throws an Exception because fake isn't a real routine in that library, but try ignores the Exception.
This might be a bit naive, but shouldn't the problem be solved at the C or linker level rather than the Perl 6 level? I mean, even in the C code, sub1 won't work. Why would you expect a higher level (Perl 6) to fix the problems of the lower-level code?
Related
I have a Modelica external C function that calls a function that is in a .dll.
In the C function in the .dll I would like to make use of the ModelicaError() function. However when
#include ModelicaUtilities.h is included a number of errors occur.
What is the correct method for doing this?
I take it I'll need to link against an existing Dymola .lib, which one? What should DYMOLA_STATIC be defined as?
Or should I be compiling the .dll in such a way that these missing functions will be available after compilation with the model?
Any insight into this would be great, Thanks
From all what I know it is currently not possible in a tool-independent way to have shared objects (DLLs on Win) depending on ModelicaError (or any other functions of ModelicaUtilities). See https://github.com/modelica/ModelicaSpecification/issues/2191 for the open issue on the Modelica Language specification.
To use ModelicaError function in a dll you send the a pointer to the ModelicaError function. To do this from Dymola create a wrapper function that passes the pointer to the ModelicaError function to the dll function. For example MathLibraryWrapper:
#pragma once
#include "MathLibrary.h"
int fibonacci_next_int_wrap()
{
return fibonacci_next_int(&ModelicaError);
}
This calls the fibonacci_next_int function which is in MathLibary.cpp in the dll. This is modified to accept a pointer to the ModelicaError function.
int fibonacci_next_int(void(*mError)(const char *))
{
(*mError)("broken");
return (int)fibonacci_next();
}
If this is run it will immediately crash with "broken".
How to call C DLL from Fortran? I don't code in Fortran but I need to do some testing on it.
Let say in the test.dll have functions:
Open()
Close()
How can I tell Fortran to use the test.dll?
I mean like C# we may use
[DllImport("test.dll")]
static extern uint Open();
I could not find any example that can help me. I would also prefer if you could provide a compiler that you use.
Update
I use Plato compiler.
I tried to load test.dll using this method. However, it popped up error message saying Error 29, Call to missing routine: _LOADLIBRARY
Here is the code. I found it online. So not sure if I'm doing it correctly.
program test
integer :: p
pointer :: q
p = loadlibrary ("test.dll"C) ! the C at the end says -
! add a null byte as in C
q = getprocaddress (p, "Open"C)
end
EDIT
Sorry. The DLL is using C and not C++
I'm trying to write some functions/subroutines in a module that call another function in the same module and running into linker errors. A toy example displaying the same behavior:
!in test.f
module m1
implicit none
contains
real function mult(a, b)
real :: a
real :: b
mult = a * b
return
end function mult
real function sq(a)
real :: a, mult
sq = mult(a, a)
return
end function sq
end module m1
program main
use m1
write(*,*) sq(2.0)
end program
When I try to compile this, I run into trouble:
[christopher#archlinux metropolis]$ gfortran -ffree-form test.f
/tmp/ccpzdTLE.o: In function `__m1_MOD_sq':
test.f:(.text+0x20): undefined reference to `mult_'
collect2: error: ld returned 1 exit status
On the other hand, compiling only (gfortran -c -ffree-form test.f -Wall) runs with no complaint.
Now this looks for all the world like a compiler error---in the module it comes up with a reference to mult_ when it really ought to com up with __m1_MOD_sq---but I have a very hard time believing that this is a compiler bug rather than me doing something stupid.
DDG didn't turn up anything useful. Most of the similar problems ocurred in splitting the module off from one main file. In those cases, things worked when the module was in the same file as the program, which is not the case here. I looked at a number of pages on modules in Fortran and didn't see anything relevant.
Can anyone point me to appropriate documentation or, better yet, explain what's going on and how I can fix it?
You don't need to declare function mult in function sq, i.e., there is no need for "real :: mult". sq already "knows" about mult since it is in the same module. The interface of mult is known to sq since they are in the same module. The interface of mult and sq are known to the main program since it uses the module. Having both the module providing the interface and the declaration is confusing the compiler.
I have a static library say "A.lib" which contains a function int foo(). I have another dll say "B.dll" which consumes A.lib and uses the function foo() and also exports some other functions. Is it possible to export the function int foo() (imported from A.lib) from B.dll so that it can be consumed in a third dll say "C.dll".
I want to know whether it is possible or not, I dont want workarounds like making A.lib available to the C.dll. Also, I am not concerned if this is a bad design or not.
Thanks very much for your patience to read this through.
I had the same requirement - just found a different solution:
Assuming that A.lib has an A.h (that is consumed by source files used to build B.dll e.g. assuming that A.h contains prototypes for functions contained in A.lib), just add the following in A.h:
#pragma comment(linker, "/export:_foo")
This will instruct the linker to export foo() when building B.dll. Note the leading underscore - it is there because that's the true name of the symbol for foo() contained in A.lib (use dumpbin /symbols A.lib | findstr foo to see it). In my example foo() was using the __cdecl calling convention, but if you use __stdcall() or compile as C++, you'll get different name decoration, so you'll have to adjust the #pragma statement above as a result.
It doesn't matter if A.h gets included by many source files in B.dll - the linker doesn't complain if the exact same definition is made multiple times.
One "advantage" to this approach is that you don't even have to use the __declspec(dllexport) specifier on foo() in A.lib ...
Yes, it's possible but any code example is language dependent.
(for example in C you may simply export a function with the same name and C.dll will see it)
I am new in systemc. There is one confusion that I am having.
I am creating a sc_module(hello_world). The sc_ctor(hello_world) has nothing between the curly braces and I just have a simple void say_hello() function inside the module which prints "hello world."
In the sc_main, I did this:
hello_world hello;
hello.say_hello();
However, I am getting an error that error C2228: left of '.say_hello' must have class/struct/union.
I tried this and it worked:
in sc_main, I did this:
hello_world hello("hi ");
hello.say_hello();
Why it is showing error in the first place? I didn't use one argument constructor.
So, instead of hello_world hello("hi ") shouldn't it be hello_world hello ? I was just trying to compare with C++ class.
Every SystemC module, whether defined with macro SC_MODULE or inherits sc_module, needs to have a module name. Constructors of SystemC modules must have one parameter of class sc_module_name.
In SystemC standard (IEEE Std 1666-2011)
Every class derived (directly or indirectly) from class sc_module shall have at least one constructor. Every such constructor shall have one and only one parameter of class sc_module_name but may have further parameters of classes other than sc_module_name. That parameter is not required to be the first parameter of the constructor.
If you are using macro SC_CTOR, it is actually a constructor with one sc_module_name parameter!
in sc_module.h:
#define SC_CTOR(user_module_name) \
typedef user_module_name SC_CURRENT_USER_MODULE; \
user_module_name( ::sc_core::sc_module_name )
I canĀ“t see nothing wrong.
In fact, it seems to me, that you have the same code like this example -> http://www.asic-world.com/systemc/first1.html
I hope you could check your with this one.
The macro SC_CTOR has created a hello(const sc_module_name name&) constructor for you. Therefor the compiler will not generate a default constructor for you to call and the object hello cannot be created.
Inbuilt constructor after macro expansion must have an argument.
It is possible that you defined your constructor as private. As a result compiler cannot name it from main.cpp.