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();
}
Related
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 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 made a dll from my project and export a function using extern "C" like the code below:
main.cpp
extern "C" __declspec(dllexport) void __cdecl VectorOfMarker(char* InAdd,vector<NewMarker>& VectorMarkers)
{
DetectSeg d;
d.VectorOfMarker(InAdd,VectorMarkers);
}
I build the project and create the .dll and .lib files successfully.
then I create a new visual c++ project and try to use this dll and mentioned function in it.
Although I copied the .dll and .lib files to the same directory but I can't use extern "C" to import my function to the 2nd project. I think that I need to change some settings in visual studio 2010 to use the functions
Can anyone help me for this?
How can I use my exported function?
Too many thanks in advance
I think you are confused as to what type of the dll you are building.
There are two typed of the dynamitic linking implicit and explicit
.
To dynamically link a dll implicitly, you create dll that exports some functions and/or variables. This will create a DLL module and .lib import library. The module that is using this type of the dll, must have header file with function prototypes and must be linked with .lib import library.
So you are linking at the compile time. Since exports are done using __declspec(dllexport) and __declspec(dlleimport) and exported functions names are decorated (mangled). They look like ?ExportedTest##YAXPAD#Z.
Another type is explicit linking and that is most likely what you are doing.
Usually for this type of DLL function are exported using .def files to produce function names that are not decorated. This also can be achieved by using extern "C" modifier to tell C++ compiler to compile function as C style, hence exported function is not decorated and usre _ (underscore).
To use this type of the DLL you have todeclare function type and parameters, call Load library, and GetProcAddress to get function pointer. Then you will be able to make a call as follows:
typedef void (*DLLVectorOfMarker)(char*, vector<int>&);
HMODULE hMod = LoadLibrary(_T("ExportTest.dll")); // your lib name goes here
DLLVectorOfMarker pfnVectorOfMarker = (DLLVectorOfMarker)GetProcAddress(hMod, "VectorOfMarker");
vector <int> VectorMarkers;
pfnVectorOfMarker("some string", VectorMarkers);
I am wondering if extern "C" is a must or not?
Only if you want to call your code from C (or a different C++ compiler, which you should treat like C).
It is to disable name-mangling.
See this article on the C++ FAQ: http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html
No, you use extern "C" to provide a C-linkage to your C++ functions, so they won't be 'decorated' like normal C++ functions and to allow them to be called from C (or Objective-C).
Function decoration is used to implement the C++ function overloading feature and gives each variation of the function a different signature while allowing the developer to use the name he assigned.
Your C++ functions will be exported automatically by simply not using the static keyword. However if you have implemented your C++ functions within a Windows DLL it's necessary to use the declspec dllexport/dllimport keywords to access them externally.
Use of extern "C" switches off name mangling. If you don't do this you may make if hard for a client of your DLL to import your symbols.
Remember that different C++ compilers have different name mangling rules and so your mangled exported names may differ from the names used on import.
However, since it is wrong to import a class from a DLL if you are using a different compiler than that used for the DLL, this is rather a moot point.
So, if you are exporting classes (usually a bad idea anyway) it is easier to leave mangling on. Otherwise switch it off with extern "C".
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.