I'm creating a package that is going to be used by R (the statistical program), I'm not an expert using this application but I have managed to create a very simple package, using the following logic, I have some classes in C++, as the code has to be compiled using the R compiler and it only allows C code, I have a wrapper C code that call the C++ methods, and later I have an R script that call the methods exposed by the C code, so basically is a communication like R <-> C<->C++.
The full tutorial that I used to create this package is found here, I add it as a reference.
Now my problem is that I need to add some functionality to the package that I already created, what I need to do is to add code for late binding to a COM object which is another product that I created and that is registered using regasm tool.
This is the c++ code that I'm using to try to late bind to the COM object, I'm trying to use IDispatch to do so:
{
...
CLSID clsid;
HRESULT hr = CLSIDFromProgID((WCHAR*)"My Com object ProgId", &clsid);
if(FAILED(hr))
return;
...
}
I didn't paste the whole code because only with these lines the compiler is giving me troubles already, the command I use to compile is
R CMD SHLIB Cclass.cc C++class.cc
Where "Cclass.cc" has the C code that call the c++ methods and "C++class.cc" is actually the C++ code.
When I compile these classes the compiler says "undefined reference to `CLSIDFromProgID#8'collect2: ld returned 1 exit status"
I"m sure I have added all the header files that I need, that's why I believe my problem is that I'm not including ole32.lib and oleaut32.lib which are static libraries.
So, my question is, how can I include this libraries in order to be able to use the methods for late binding, like CLSIDFromProgID(...) or QueryInterface(...). Also if anyone believes that my problem is not linking this libraries, but something else, it would be great if can point me to which my problem may be.
Also have in mind that I need to link with those statics libraries in a way that they can be compiled without problem by the R compiler, which if I'm not wrong is a merely c compiler.
I've not tried doing this with C/C++ but rather with Fortran. I had a similar problem in that some standard IO libraries weren't being included in the library I was created. In the end I just included them all and compiled using the Fortran compiler. I didn't use any of the R compiler utilities, just compiled as if I were compiling a static Fortran library normally for use with anything else. This worked fine.
A debug path might be to compile as a static library using gcc (or whatever you're using) then try to include and call that static library from another C program, then if that works try with R.
Hope this is helpful, writing these R packages is pretty hard unless you're using vanilla C or Fortran as far as I can tell.
Related
I am trying to compile C++ code to wasm and then embed it in other C++ code with wee8 (v8's wasm-api). Currently I'm getting a Segfault on instantiating the module:
auto instance = wasm::Instance::make(store, module.get(), imports);
Note that I have no problem embedding code that I write as .wat and convert to .wasm, so the problem is specifically with embedding code compiled with emcc.
I am guessing that what I'm missing is WASI support in wee8? Does it exist? How can I enable it? Alternatively: can I ask emcc not to generate any WASI calls?
Here is a minimal example which results in:
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
In cpp42.cpp:
int main() {
return 42;
}
Compiling this to wasm with:
emcc -O3 cpp42.cpp -o cpp42.wasm
Inspecting the compiled wasm module with wabt's wasm2wat shows that it contains the following import
(import "wasi_snapshot_preview1" "proc_exit" (func (;0;) (type 0)))
Which I suspect to be the cause of the problem.
Then embedding with wee8 like in the examples in the repo and like I do with other wasm files causes the segfault mentioned above.
Just as another check: running
wasmer cpp42.wasm
echo $?
> 42
Works without a problem.
I can answer part of your question:
I'm missing is WASI support in wee8? Does it exist?
No, wee8 does not implement WASI. Adding such support is theoretically possible, but not currently scheduled to get done.
You can implement it yourself in your wee8 embedder, and make it available to loaded modules via imports. Most (or all?) of it could probably be a reusable (among many engine implementations) library, potentially offered and maintained by the WASI project itself. (I don't know whether such a library exists already.)
You didn't say what imports object you're currently passing; it needs to be an array of wasm::Extern* pointers that's at least as long as the imports of the module, and ordered equivalently (i.e. imports[i] will be the module's ith import).
(I agree that the Wasm C/C++ API is very barebones currently. Unless/until that is changed, you'll have to build any convenience mechanisms yourself. It's all possible with the information that's available, it's just clearly less convenient than instantiating Wasm modules from JavaScript.)
How to directly run a c++ file present in read-only storage like CD-drive without making executable files using g++? There must be some arguments for that to work.
The process of a C/C++ program when you make one till you run it:
You write the program's source code.
The compiler comes in here and compiles the source code to object files.
Note: Remember that the program cannot be executed at this stage. It's only an object file. You'd know this if you have worked on bigger size programs, but if you haven't here is how it works. Remember using those header files in your programs? These header files just tell the compiler that there are some things that are not defined in your program. They are somewhere else. So your compile compiles the program to the object file leaving out things that have a prototype (which is in the header files).
This is a very important point. Here a program called 'linker' comes into play. What linker does is to take all the object files created by compiler and combines them into one. Say for example your compiler created a single object file. Now, you're using math library or anything from standard library. The compiler-linker package (often called only compiler) comes with object files for these standard library definitions. So, linker takes your object file and combines it with other object files from the package and then converts it to an executable file. This is the file that you can run. Nothing else is runnable directly.
To run source code the process is explained already, we have to use the g++. Now
What I understand from your question is that you want to know if a program can be run once it's compiled and linked properly (hence an executable has been generated). Answer to that would be yes.
Alternatively, may sound strange, there is an interpreter I know called Cling that can be of use to bypass the compilation of C++ program.
After all C++ is generally seen as a compiled language. However, any programming language can be implemented as a compiler or as an interpreter and Cling happens to be an interactive C++ interpreter based on LLVM and Clang.
Take a thorough look at this
I have a body of 'normal' C++ code which I'm trying to make usable by a C# client. I have successfully compiled this with /CLR. I now know that this isn't enough: I have to introduce managed wrapper classes ("ref") to make the code callable from managed code. This question is about what happened before I introduced the ref classes.
I found that the native C++ classes were visible from the C# project, and that I could write
MyNativeClass mnc = new MyNativeClass();
... although any attempt to call a method on the instance was rejected by the compiler. I found that when I ran the C# code, the MyNativeClass constructor was never called - indeed the attempt to instantiate mnc seemed to produce no code at all, so completed without error.
How was C# interpreting the native types in my project? Why did the compiler apparently allow me to instantiate an instance? Why were methods treated differently to the types themselves?
You made two mistakes to make this code work. First is that you declared the C++ class public, like this:
public class MyNativeClass {};
This is not syntax that makes sense in C++ but it is allowed by the C++/CLI compiler. Omitting public would have produced an error message in your C# code, CS0122: "Foo is inaccessible due to its protection level".
Second mistake is that you compiled your native C++ class with /clr in effect. Which works fine, any C++03 compliant code can be compiled to IL and gets just-in-time compiled to machine code by the jitter, just like managed code. And executes fine as well. It is however not efficient to do so, you lost the advantage of having the compile-time optimizer available to produce the best possible code. It still gets optimized, but now by the jitter which doesn't have the same luxury of time available to do as good a job as the C++ code optimizer can do. You avoid this by moving the C++ code in a separate source code file so you can compile it without /clr in effect. Or by using #pragma managed in your source code.
Anyhoo, what you ended up with was an assembly that indeed contains a declaration for MyNativeClass that any managed compiler can see. Something you can see for yourself by running ildasm.exe on the assembly. You'll see that it gets embedded as a value type type. Just a blob of bytes with no constructor and no methods. Which is a decent match for a C++ object from a managed point of view, just bytes that can be stored anywhere a value type can be stored. Declaring a variable of that type in C# works but doesn't do anything useful, it just creates the blob with all bytes set to 0. The only possible use of this declaration is that you can declare a typed pointer to the class and pass it around, that's all.
UPDATE After some digging I found this to be a part of some workaround that passed a file handle from C++ to Fortran using a stub for OPENPIPE. OPENPIPE simply returns an externally declared file handle, doing absolutely nothing with a pipe. OPENHOLDFILENAME actually creates a file, but I'm still confused about what DFWIN has to do with this. Was it required to provide a function declaration for OPENPIPE? If so, they why was it also declared as EXTERNAL in the Fortran code?
I was given the task of compiling legacy Fortran on the GCC toolchain. I've already successfully compiled a few of the source files, but have hit a snag regarding the DFWIN module which links up to some Win32 API functions. It apparently uses some Win32 pipe functions, and I need to replace this with a modern equivalent that works with gfortran (the old compiler was Compaq Visual Fortran).
First, I see the DFWIN module included, as well as some external functions:
USE DFWIN
EXTERNAL OPENPIPE
EXTERNAL OPENHOLDFILENAME
Here is an example of how OPENPIPE is used:
OPEN(UNIT=INN,FILE=
1 '\\.\pipe\input.txt',
1 FORM='FORMATTED',STATUS='old',readonly,
1 USEROPEN=OPENPIPE)
What module can I use to replace these calls on modern Windows/Linux systems using gcc/gfortran?
EDIT: Our priority is to get this running on Windows, but in the future we want to deploy on Linux as well.
I have a project compiled using __cdecl calling convention (msvc2010) and I compiled boost using the same compiler using the default settings.
The project linked with boost but I at runtime I got an assert message like this:
File: ...\boost\boost\program_options\detail\parsers.hpp
Line: 79
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
There are the following questions:
what calling convention does boost build with by default on Windows (msvc2010)
how to I compile boost with __cdecl calling convention
why boost wasn't able to prevent linking with code with different calling conventions? I understood that boost has really smart library auto-inclusion code.
Update #1
It looks that boost does compile and link with proper calling convention, still at runtime I get the above problem. I did a sample application using the same code and it works but in my application it fails. The only difference could be from project configuration or includes/stdafx.h
Just use
bjam ... **cxxflags=/Zp4**
while building boost libraries.
As far as I know there's not way to make C++ use cdecl calling conventions (see MSDN Calling Convention). The C++ method calling is just different from C. The only opportunity that you have to use one of the C calling conventions is for functions, which include class static functions in C++. If you know that's the case you can try forcing the option when building by adding the option during the build:
bjam cxxflags=/Gd ...
(see BBv2 Builtin features)
Or to make it "permanent" set up a user-config.jam with your compiler and add it to the build options for all BBv2 msvc builds (see BBv2 Configuration and related docs). As for you other questions:
Boost uses the default calling convention MSVC uses, except for cases where it overrides it at the code level. I don't know where those are as they are library specific. So you'd have to search the code for the "__*" code decorators.
See above for partial answer.
Detection; there are two reasons: There is a limit to how many different options we can reasonably detect for for building as it's an exponential growth of different possible variations so we limit it to the most important cases. And in the case of calling convention, it's not actually possible since it's something that can be changed on a per function basis.
I found the cause of the problem inside one of the shared property files: <StructMemberAlignment>4Bytes</StructMemberAlignment>
If I remove it the code will work. Still, I'm not sure why this is happening and how could I solve it without removing the above code (that was required by another library).
I added another question regarding boost and structure member alignment.