I have a .cu file in a 64x VS2010 project. This project is configured to extract a .mexw64 file. Bellow there is the example I run. Inside the mex function I want to use some functions of the Armadillo linear algebra library. So When the #include "armaMex.hpp" is used the compiler return some errors:
error C3203: 'fixed' : unspecialized class template can't be used as a template argument for template parameter 'T1', expected a real type c:....\armadillo-4.200.0\include\armadillo_bits\Mat_meat.hpp
error C2955: 'arma::Mat::fixed' : use of class template requires template argument list c:\ ....\armadillo-4.200.0\include\armadillo_bits\Mat_meat.hpp
error C1903: unable to recover from previous error(s); stopping compilation c:\ ....\armadillo-4.200.0\include\armadillo_bits\Mat_meat.hpp
I can not figure out what is causing these errors. Could you please give an explanation?
#include "mex.h"
#include "armaMex.hpp"
void
mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mexPrintf("hello!\n");
}
PS: CUDA SDK 5.5 64x, VS2010
This is a known limitation of nvcc (technically cudafe++, I think). nvcc uses file extension to determine whether a given source file should be processed for device code or passed to the CUDA preprocessors and then the device compiler. It looks like that compilation trajectory can't correctly parse some of the very complex declarations that Armadillo contains, and the compile fails. This is known to happen with Boost, Eigen and QT. I guess Armadillo is in the same boat.
The solution is to not import Armadillo headers inside a .cu file. Put your host boost code in a .cc file, device code and kernel launches in a separate .cu file and make some thin wrappers to access the kernel calls from the .cc file. You can still pass all the source to nvcc to compile into a single object file, but separating the Armadillo imports from the device code eliminates the problem of the front end choking on the complex template declarations Armadillo contains.
Related
Got a new issue I've not come across before that's appeared when using the Espressif ESP32 ESP-IDF standard setup under VSCode. It uses the GNU compiler.
I'm getting "multiple definition of" errors on variables that share the same name, but which should be local.
So I use a .c and .h pair of files approach.
In my .c files I do this at the top
#define IO_EXPANDER_C //<<<This is a unique define for this file pair
#include "io-pca9539.h"
In my .h files I do this:
#ifdef IO_EXPANDER_C
//----- INTERNAL ONLY MEMORY DEFINITIONS -----
uint8_t *NextReadDataPointer;
//----- INTERNAL & EXTERNAL MEMORY DEFINITIONS -----
//(Also defined below as extern)
int SomeVariableIWantAvailableGlobally;
#else
//----- EXTERNAL MEMORY DEFINITIONS -----
extern int SomeVariableIWantAvailableGlobally;
#endif
It's a great simple system, any other .c file that includes the .h file (without the #define above its include statemnt), gets all of its extern variables, none of its local variables.
But, compiling in VSCode with my ESP-IDF based project, I'm getting "multiple definition of" errors relating to "NextReadDataPointer"
I use the same variable name NextReadDataPointer in another file pair in just the same way, but it's never declared anywhere as extern and each file pair uses a separate #define (IO_EXPANDER_C and LED_C). I do this all the time normally and I can't see any obvious mistakes.
I've never seen a C compiler do this before, it's as if it's mixing up the local definitions somehow. A #define should only have scope in the file it is declared in and in any includes within that file.
Even odder, the error is not generated if the project is built but a function is called from just one of the file pairs that share the same local variable name. It's only generated when functions are called from both file pairs from my main application.
Can anyone shed light on whether the GNU C compiler does something funky for a standard ESP-IDF project as it's got me baffled?
uint8_t *NextReadDataPointer; creates a variable which is visible across all translation units, i.e. it's the opposite of "private". If you include this header in multiple c files and the linker tries to link those together; it'll see a conflict. The keyword you're looking for is static, for example static uint8_t *NextReadDataPointer; creates a variable that is not visible across translation units. The reason you don't see the problem if calling a function from only one of those two files is because in this case the linker doesn't bother looking into the other one.
Personally I'd avoid such clever preprocessor hacks because it's quite difficult to see how files include one another and debug the resulting problems. I'd suggest sticking to the standard way of declaring shared things in header files and keeping the private stuff inside the c file (prepended by static).
I have an embedded IoT project that I like to first develop in part by using PC tools such as VisualStudio. My embedded project has only a flash memory for a file system, and I'd like to redirect fopen fread etc. to my own private implementation on Windows. But what I'm encountering is an inability to have my private CRT library take precedence over the built-in CRT (e.g., built-in behavior driven by /MD compiler switch).
I have a simple three project solution.
Project 1 is a test executable. It has a one line main:
int main()
{
test();
}
Project 2 and 3 are static libraries. Project 2 has:
#include <string.h>
#include <stdio.h>
void test()
{
printf("%s\n", strchr("x", 'x'));
}
Project 3 has:
char * strchr(const char * s, int c) // exact signature of MSVC
{
return "overridden";
}
I expect output to be overridden but instead it is
x
But if I add this to Project 1:
printf("%s\n", strchr("y", 'y'));
The output will be
overridden
overridden
First one from test() in library, second from executable main() directly.
Any suggestions?
The linker resolves symbols on a first match basis - priority to separately linked .obj files, then .lib files in the order presented to the linker of the command line. So you can normally override a library symbol just be linking your own replacement. I have never tried it with MSVC, and it is a somewhat brutal approach.
An alternative solution that does not rely on specific linker behaviour is to use the pre-processor to replace standard symbols with your own alternatives. For example:
#if defined _WIN32
#define fopen test_fopen
FILE* test_fopen( const char * filename, const char * mode ) ;
#endif
add the other macros and declarations you need in a header file called testlib.h for example then use a "forced include" (/FI testlib.h in MSVC) to invisibly include the test interface everywhere. Then when built on Windows, all fopen calls will be replaced with test_fopen calling your replacement functions instead.
If the problem is caused by CRT usage in a static library only, and linker is finding MSVCRT DLL export lib before it finds private CRT static lib, a workaround might be to force a reference to the private CRT in the executable source files.
Example matching code above, placed in main as a global:
static char * (*p_strchr)(const char *, int) = strchr;
It is less than ideal but it alters linker search order in a reliable way.
More findings
There may be combinations (that I don't totally understand) where the linker will emit a LNK1169 "one or more multiply defined symbols" (more than one definition) linker error. For example, it might say fopen is defined more than once, and if you reverse the order of the private and MS libraries on the command line, then it might say fread is defined more than once. Perhaps it is caused by MSVC lib having DLL export signature, and the private lib being an import symbol. The behavior is hard to determine as it doesn't error on all of the functions that are being overridden.
If it is possible to switch all private libraries to /MT compiler switch (use static CRT), then the LNK1169 problem is resolved.
So I wrote the following code first and was getting a compile error. After reading this answer :
static array class variable "multiple definition" C++
I modified my code and moved the static variable definition to a cpp file and it executes fine, but I'm unable to understand that when I have used pre-processor guards, why is it showing multiple definition error ?
#ifndef GRAPH_H
#define GRAPH_H
#include<iostream>
#include<vector>
using namespace std;
struct node{
int element=0;
static vector<bool> check;
node(){
if(check.size()<element+1)
check.resize(element+1);
}
};
vector<bool> node::check;
#endif
So, this is a common mistake of misunderstanding how the header guards work.
Header guards save multiple declarations for one compilation unit, but not from errors during linking. One compilation unit implies a single cpp file.
E.g. apple.cpp includes apple.h and grapes.h, and apple.h in turn includes grapes.h. Then header guards will prevent the inclusion of the file grapes.h again during compilation.
But when the process of compilation is over, and the linker is doing its job of linking the files together, then in that case it sees two memory locations for the same static variables, since the header file was included in a separate translation unit, say apple2.cpp to which its trying to link, thus causing the multiple definition error.
The only way to resolve it is to move the definition of the static variable to a cpp file.
I have to use some functions from math library on a CC3200 Project. This project has to use freertos and the IDE is CCS. With this combination, the compiler show these warnings:
/ymath.h", line 550: warning #225-D: function "_ftoi" declared implicitly
/ymath.h", line 592: warning #225-D: function "_hi" declared implicitly
/ymath.h", line 594: warning #225-D: function "_lo" declared implicitly
/ymath.h", line 604: warning #225-D: function "_lo" declared implicitly
To reproduce the problem, we have to import to CCS the "freertos_demo" project from CC3200SDK_X.X.X and in the main.c file add the include directive: #include <math.h> only that.
if we compile the project we get the warnings.
Thanks in advance.
JM
I'm not sure what this has to do with FreeRTOS as the functions that are generating the warnings are not used in the FreeRTOS Cortex-M4 port. Perhaps they are only used in demo code, in which case, can't you just include the necessary header files in the demo source files (this won't effect FreeRTOS at all)? Where did you get the demo from? It's not a project from the FreeRTOS distribution.
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"
}