Using modelica function as input to external "C" function - c

I am trying to call an external C function in modelica with a function as an argument.
So the C function needs to take a modelica "function" as input. Is it possible to do that in modelica ?
For example :
function foo
input Function fun;
output Real bar ;
external "C" bar = myCFunction(fun) annotations(...);
end foo;
function Function
input Real u;
output Real y;
algorithm
y := u*2;
end Function;
When I use the "check" option, I get some error stating fun is undeclared which I don't if I do not use a function as input.
I looked online and in the use manual of dymola but I haven't found an example stating it was possible, nor impossible.

No, I don't think that's possible. You can check the Modelica Specification about allowed input types to external functions.

Related

Using modules in Fortran: Undefined reference to `parse_'

I am trying to use the parse routine described here to parse a string in Fortran90. When following the link in the document one can download a .zip with two f90-files, which I have done. I have then compiled them gfortran -c precmod.f90 && gfortran -c stringmod.f90. I have also added use strings to my program.
Despite of this, I receive the following error when compiling (gfortran stringmod.o precmod.o calcs.o server.o):
calcs.o: In function `calculate_':
calcs.f90:(.text+0x174): undefined reference to `parse_'
collect2: error: ld returned exit status 1
calcs.f90 is shown below and server.o is a server written in C that should be invoked by calcs.
program name
use strings
use iso_c_binding, only: C_CHAR, C_NULL_CHAR, C_INT
implicit none
! type declaration statements
character(255) query
integer calc, ans, portnum, calculate
interface
subroutine server(portnum) bind(C, name="server")
use iso_c_binding, only: c_int
integer(kind=c_int), value :: portnum
end subroutine server
end interface
! executable statements
print *, "Please provide me with a port number. Plz. <3"
read "(1i9)", portnum
call server(portnum)
end program name
function calculate(query)
implicit none
character(255) query, op
integer length, i, calculate
integer, dimension (:,:), allocatable :: inputarray
call parse(query, ' ', inputarray, length)
do i=1,size(inputarray)
print *, inputarray(i, 1)
end do
calculate = 5
end function calculate
I have tried to add public to the top of stringmod.f90.
When we have something like
program
end program
function func()
end function
then the function func is an external function, even when this is given in the same source code file as the main program. This external function knows nothing about the main program, and in turn the main program knows little about the external function.
Part of this lack of knowledge is that, in the example of the question, the fact that the subroutine parse has an explicit interface (through the module) in the main program is irrelevant to calculate.
That is, the function calculate has its own scope and has no host. To gain access to the module procedure parse it can itself use the module strings:
function calculate(query)
use strings, only : parse
implicit none
end function
There is a hint to this lack of being aware that parse is a module procedure in strings. The name decoration in parse_ (that single trailing underscore) is a common way to mangle an external procedure. Module procedures (without bind(c)) generally have much more elaborate symbol names.
Finally, I'll repeat something from the comments. Earlier, I said that the main program knows little about the external function. In the main program we have the declaration
integer ... calculate
which says that the external function calculate (which has an implicit interface) has a return type of integer. The function, in this case, could instead be made an internal function
program
use strings, only : parse
contains
integer function calculate
end function
end program
and not only does the function calculate have an explicit interface (removing also the need for that return declaration in the main program) but it also has access to parse through host association.

c programming language - declare() function

I am writing a c program and came across the declare() function.
When I searched on web for it, I received results about function declaration and function definition.
I would like to know about the declare() function in c,what it does, what are its parameters, etc.
Here is block of code that uses the function:
char file[50];
strcpy(file,"IS_inst.txt");
declare(file,IS_ins,&IS_inst_count);
strcpy(file,"DS_inst.txt");
declare(file,DS_ins,&DS_inst_count);
strcpy(file,"AD_inst.txt");
declare(file,AD_ins,&AD_inst_count);
strcpy(file,"REG_OPERAND.txt");
declare(file,REG_oprand,&REG_op_count);
There is no such function in C, it might/should be defined in your program.
There is no function called declare in the C standard library, or, as far as I know, in any commonly used add-on library.
There's nothing special about the name declare. It might as well have been named foobar.
It must be declared as a function or as a macro somewhere in your program. If your development environment has such a feature, try querying the name (perhaps you can hover over or right-click on the function name if you're using an IDE). Or just search the source file and any headers it #includes for the name declare. grep and ctags are both useful tools for this kind of thing.
You should implement this function in your code
Declare function means you are assigning a function's return type. There is no built in function named as "Declare Function". Suppose, you want to create a function to add numbers. So, you can name the function as "Add". In c programming you have to declare the function type at first example: for two integers addition the function type should be int Add() {}

Variadic function in Ada (C - Ada binding)?

I am working on a project which uses C - Ada language binding. A function in C will call a function in Ada side. I want to make a variadic function in Ada which can receive a variable number of arguments sent from the C function. I also wanted to send different types of args at the same time like int, char, enums, etc at the same time. Is it possible to have this type of mechanism?
The forthcoming Ada standard Ada 202x is planning to provide support for calling C variadic functions.
You would then be able to write;
package C renames Interfaces.C;
procedure Printf (Format : in C.char_array)
with Import => True, Convention => C_Variadic_1, External_Name => "printf";
You cannot create a variadic function in Ada. You can simulate a variadic function is a couple of ways.
Ada allows you to specify default values for functions and procedures. One need not always specify the values of the default parameters if you want to use the default values.
You can define one or more of the parameters as a variant record.
It is not possible to call any C variadic function from Ada in a portable way!
One of the reason - some ABIs use special ways/registers to pass float values. This mean C compiler will use this registers, due to it's unknown in advance whether argument is float or not. Ada compiler will not use this registers (since you can't put float parameter in Ada wrapper function declaration). As result you will get crash, stack corruption or any other undefined behavior.
Particularly AMD64 ABI specifies:
%rax - with variable arguments passes information
about the number of vector registers used
%xmm0–%xmm1 - used to pass and return floating
point arguments
The only portable solution is using C wrapper with fixed number of parameters, then bind it as usual.
You can use 'address or the package System.Address_To_Access_Conversions and 'access (or 'unchecked_access) to generate addresses of each item you want to pass.
type Address_Array is array (positive range <>) of System.address;
function C_Caller(Params : Address_Array) return Integer is begin return 0; end;
X, Y, Z, Result : Integer;
begin
result := C_Caller(Address_Array'(x'address, y'address, z'address));
...then you'll need to pragma import the actual function.

Linking LLVM JIT code to external C++ functions

I'm writing a LLVM scripting engine that JIT compiles scripting code in a custom language. My problem is that I'm unable to call external functions (even the C99 erf() function is failing).
For example if I extern "C" the erf function,
extern "C" double erft(double x){
return erf(x);
}
and create a function with external linkage
std::vector<const Type*> Double1(1,Type::getDoubleTy(getGlobalContext()));
FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),Double1,false);
Function *erft = Function::Create(FT,Function::ExternalLinkage,"erft",TheModule);
get the following error message when running my script with erft(0.0) :
LLVM ERROR: Program used external function 'erft' which could not be resolved!
Doing the mapping manually,
void ExecutionEngine::addGlobalMapping( const GlobalValue * erfF, void * erft);
will get me the following error:
declaration of `void llvm::ExecutionEngine::addGlobalMapping(const llvm::GlobalValue*, void*)' outside of class is not definition
Obviously I'm doing something very wrong. Any help would be much appreciated
Assuming you haven't disabled it (by calling EE->DisableSymbolSearching()) then LLVM will use dlsym() to find the symbols in the JIT program itself. Depending on your platform, that might mean that you need to build your JIT with -fPIC, or that it might not be available at all (such as on Windows).
Aside from automatic symbol searching, you can always register the individual functions yourself using EE->addGlobalMapping(GV, &function) where GV = the llvm::Function* function declaration that matches the native function you're calling. In your case with ertf() that's:
EE->addGlobalMapping(erft, &::erft);
Note that you named the global function erft() and the local variable erft, hence the "::". Please pick different names next time!
This might be happening because you forgot to add the "libm" depedency, try using:
[your module]->addLibrary("m");
See here for more information about the Module::addLibrary().
I don't know llvm, but this make no sense:
void ExecutionEngine::addGlobalMapping( const GlobalValue * erfF, void * erft);
That defines a new function in C++. What you need to do is somehow register your function with LLVM. Defining that function is like trying to add new methods to the LLVM classes, not what you want to do.

Intrinsic function, cannot be defined (C)

I implemented a function called abs(). I get this error:
Intrinsic function, cannot be defined
What have I done wrong?
I'm using Visual Studio 2005.
Intrinsic function, cannot be defined
In this case, intrinsic means that the compiler already has an implementation of a function called abs, and which you cannot redefine.
Solution? Change your function's name to something else, snakile_abs for example.
Check the MSDN documentation on the abs function for more information.
The problem is not being in a header or not.
The problem is that intrinsic functions, i.e., functions that the compiler recognizes and implements itself, generally with optimizations that wouldn't be available in C code alone, cannot be defined.
The names of all mathematical functions (see math.h)
The names of all mathematical functions prefixed by 'f' or 'l'.
Are reserved for the implementation.
Defining static int abs(int x) { ... } should be legal, but simply int abs(int x) { ... } has undefined behavior, and thus one reasonable thing a compile could do is issue an error.

Resources