How can I call a C++ function from a C program, is it possible?, and if it is how can I do it?. Thank you.
If you are trying to call a C++ function from C, then you are probably running into name mangling issues. The compiler does this in order to support function overloading and other features of C++.
You can use extern "C" to inform the C++ compiler that the function CMACInit() will be called from C code:
extern "C" CMACInit() { ... }
When declared in this way, the C++ compiler will not mangle the name and will set everything up so the function can be called from C code.
Related
The supported languages are C and Java. Could Rust compile to a static DLL that is compatible with the Oracle interface?
https://docs.oracle.com/database/121/ADFNS/adfns_externproc.htm#ADFNS010
Since C functions are supported you can do this like explained here.
Basically you specify in the Cargo.toml, that you want your library to be compiled into a DLL:
[lib]
name = "your_library_name"
crate-type = ["cdylib"]
and then you can write your Rust functions like this:
#[no_mangle]
pub extern "C" fn rust_function_to_be_called_from_plsql() {
}
Additional Info
You should also be able to do the reverse (which is explained in the linked docs) and call a PLSQL Procedure compiled into a DLL from Rust, also by using the C interface, like so:
#[link(name = "mylib")]
extern "C" {
pub fn my_exported_plsql_function();
}
I have been using cgo to interface between Go and C. However, when trying to do the same for Go and C++, I get a compile error every time I attempt to call a function. Using go build . from the code's directory, I get the following errors:
./main.go: In function 'void _cgo_3612c872201c_Cfunc_getint(void*)':
./main.go:48:53: error: invalid conversion from 'void*' to '_cgo_3612c872201c_Cfunc_getint(void*)::<anonymous struct>*' [-fpermissive]
./main.go:54:4: error: invalid conversion from 'void*' to '_cgo_3612c872201c_Cfunc_getint(void*)::<anonymous struct>*' [-fpermissive]
I've put a super simple example below which shows the problem.
main.go:
package main
/*
#cgo CFLAGS: -x c++
int getint()
{
return 1;
}
*/
import "C"
import (
"fmt"
)
func main() {
fmt.Println(C.getint())
}
Does anyone know if this is a bug in cgo, or something wrong with how I wrote the code? According to the cgo documentation, C++ is supported. I'm using Go version 1.7.5 for linux/amd64.
Thanks so much!
I may be wrong, but I think cgo supports C++ only in the sense it knows how to invoke a C++ compiler on the non-Go files which looks like containing C++ source code, and that's all.
The problem is that C++ compilers use so-called "mangling" for the symbols made exported from the compiled files. Exporting symbols were originally
intended only for C-like languages, where all which can be exported are plain
functions and variables, but C++ adds classes and function overloading,
and to export such symbols from compiled ("object") files, a C++ compiler
needs to "mangle" them using certain schema to encode names of classes
and types of arguments in these names. What's worse, each C++ compiler
brand uses its own mangling schemas.
So I think while cgo is able to compile C++ code, it sort of assumes that
all the symbols exported (to be used by Go) in your C++ files are
wrapped in extern "C" { ... } (see this).
If you need calls to "native" C++ exported stuff, you'd need to use
SWIG I reckon.
I am trying to write an assembly function without using c prototypes.
For some reason it looks like the gcc doesn't allow to use extended asm in the global context.
Please consider the following code that compiles succssefully:
void *g_var;
void foo()
{
asm ("stx %%i7, [%0]"
:"=r" (g_var));
}
When I am also trying to define the prototype using asm, as follows:
asm(".global foo2\n\t"
"foo2:\n\t");
asm ("stx %%i7, [%0]"
:"=r" (g_var));
the compiler give me the following error as if extended asm cannot be used in global context.
foo.c:151:2: error: expected ')' before ':' token :"=r"
(return_addr)); ^
Please note that when I don't use extened asm as follows, the compiler approves the code:
asm(".global foo2\n\t"
"foo2:\n\t");
asm("jmpl %o7 + 8, %g0\n\t");
Thanks.
From the GCC Documentation:
Note that extended asm statements must be inside a function. Only basic asm may be outside functions (see Basic Asm). Functions declared with the naked attribute also require basic asm (see Function Attributes).
So the answer to your question is that - no it isn't possible to use extended assembler templates outside a function in the global context. As you have found basic assembler statements are allowed.
I want to use my school custom library in a C++ project but the library linking seems not working... When I create my program in C and I try to compile it, it work...
See by yourself:
I think that the X11 and/or Xext libraries dependencies of the Mlx are in cause, there can be some
#if __cplusplus
void *x11_mlx_function_wanted(void);
#endif
I had already check if the mlx contains some check like that and I saw nothing.
Thank you in advance
EDIT
And I succeed in objective-c.
The problem is C++ name-mangling. If you declare a function in C11, it ends up with a "mangled" name, which encodes the namespace and the types of the arguments. That's necessary because in C++, various overloads can exist for the same function name. The overloads are independent functions; they do not even have to be in the same object library.
In the object library itself, the functions will have ordinary C names. But since the header file is processed with a C++ compiler, the declared functions will be named as though they were C++ functions.
One possible solution might be to declare all the included functions to be C functions:
extern "C" {
#include "/usr/X11/include/mlx.h"
}
I've got an application written in pure C, mixed with some functions that contain pure ASM. Naked attribute isn't available for x86 (why? why?!) and my asm functions don't like when prologue and epilogue is messing with the stack. Is it somehow possible to create a pure assembler function that can be referenced from C code parts? I simply need the address of such ASM function.
Just use asm() outside a function block. The argument of asm() is simply ignored by the compiler and passed directly on to the assembler. For complex functions a separate assembly source file is the better option to avoid the awkward syntax.
Example:
#include <stdio.h>
asm("_one: \n\
movl $1,%eax \n\
ret \n\
");
int one();
int main() {
printf("result: %d\n", one());
return 0;
}
PS: Make sure you understand the calling conventions of your platform. Many times you can not just copy/past assembly code.
PPS: If you care about performance, use extended asm instead. Extended asm essentially inlines the assembly code into your C/C++ code and is much faster, especially for short assembly functions. For larger assembly functions a seperate assembly source file is preferable, so this answer is really a hack for the rare case that you need a function pointer to a small assembly function.
Good news everyone. GCC developers finally implemented attribute((naked)) for x86. The feature will be available in GCC 8.
Certainly, just create a .s file (assembly source), which is run through gas (the assembler) to create a normal object file.