MSVC compiler error for external variables and OpenMP's threadprivate - multithreading

I am trying to compile a c++ application using MSVC (Compiler Version 19.32.31329 for x86). The author of the application has complied it successfully using GCC 8.3, 9.3, and 10.3.
I run into an error when I enable OpenMP for parallel computing - in particular in the random.h and random.cpp files. I have found a small code snippet that throws the same compile error on MSVC but has no issues when compiled with GCC according to the author.
#include<omp.h>
#include<iostream>
struct point2d
{
int x;
int y;
#ifndef DECLARE_AS_POD_TYPE
point2d() {}
#endif
};
int main(int argc, char* argv[])
{
using namespace std;
extern point2d myPoint;
#pragma omp threadprivate(myPoint)
//point2d myPoint;
myPoint.x = omp_get_thread_num();
cout << myPoint.x << endl;
}
The MSVC error I get is error C3053: 'myPoint': 'threadprivate' is only valid for global or static data items
I am pretty new to OpenMP but have done a fair amount of googling. I am not the first person to have this issue but I have not found a solution that works for me. In particular, I have looked at:
Using threadprivate directive in Visual Studio
Threadprivate directive after external declaration of global variables
OpenMP threadprivate directive is not working.
I am using this application as a bit of a learning exercise so I am happy to make changes to the code but I have tried quite a few permutations and I am not able to make progress.
Any suggestions are welcome.

Related

Suppress anonymous structs warning with Clang - "-fms-extensions" doesn't work

I have an Xcode project that I compile with Clang using some 3rd party library with Visual Studio C code.
In the 3rd party library anonymous structs are used in header files (I can't really change that). Thus I get this warning:
"myfile.h:47:17: Anonymous structs are a GNU extension"
As described here, I tried to pass "-fms-extensions" in the C flags of my Xcode project:
http://clang.llvm.org/docs/UsersManual.html#microsoft-extensions
No luck. Any idea how to get rid of that warning?
Adding -Wno-microsoft did not work for me.
Using this small test program
typedef struct test_struct
{
struct
{
int a;
int b;
};
int x;
} Test;
int main(int argc, char **argv)
{
Test test;
test.a = 0;
}
using -Wno-gnu disables the warning
Version is Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
You can simply use -Wno-microsoft to hide the warning.

vector<int> - missing type specifier

This is the header of a class I am working on in Visual C++ Express 2010:
/* custom class header to communicate with LynxMotion robot arm */
#include <vector>
using namespace System;
using namespace System::IO::Ports;
public ref class LynxRobotArm
{
public:
LynxRobotArm();
~LynxRobotArm();
void connectToSerialPort(String^ portName, int baudRate);
void disconnectFromSerialPort();
void setCurrentPosition(int channel, int position);
int getCurrentPosition(int channel);
void moveToPosition(int channel, int position);
private:
void initConnection();
SerialPort^ serialPort;
array<String^> ^serialPortNames;
String^ portName;
int baudRate;
vector<int> currentPosition;
};
Everything worked fine until I changed the last line int currentPosition to vector<int> currentPosition. If I try to compile / debug now, I get these error messages:
error C2143: syntax error : missing ';' before '<'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C2238: unexpected token(s) preceding ';'
I checked MSDN for some more info on these error codes, but I cannot figure out what is wrong with the code. Any ideas?
vector is template defined within std namespace, thus you should write std::vector<int> instead of vector<int>.
Alternatively you could write using namespace std; at the beginning of this file, but note that this is considered bad practice since it could cause some of names of your classes to become ambiguous.
You are using vector. Vector is contained with the namespace std. Namespaces encapsulate the normal scope of a variable/class. You cannot access elements within a namespace without resolving the scope somehow. There are 3 main ways to go about this:
#include <vector>
using namespace std;
You don't generally want to use this one, it will create issues because it allows you to see ANY function/class contained in the namespace std. This is bound to cause naming collisions.
Next way is:
#include <vector>
using std::vector;
This way is a little better. It makes vector visible to anything in the file or any file that includes said file. It is perhaps completely harmless in a .cpp file, because you shouldn't be including .cpp files anyways. And you should know what symbols you're or not. In the scenario of a .h/.hpp file, you may still not want to use this. Any file that has your .hpp file included their source code will see class vector as the name definition. This could be bad for users of your code, because they may not be expecting that symbol to be defined. In the case of an hpp file, you should always use the following:
#include <vector>
class myClass{
private:
std::vector myVector;
};
Using namespaces this way guarantees that it will only be visible exactly where the symbol is used, and nowhere else. This is the only way I'd use it in a .hpp file.

Export native type from C++/CLI project

How do I export the methods of a native class defined in a C++/CLI project? Here's what I have:
The .h file:
#pragma once
#ifdef COMPILE_PRODUCER_LIB
#define PRODUCER_LIB_EXPORT __declspec(dllexport)
#else
#define PRODUCER_LIB_EXPORT __declspec(dllimport)
#endif
public class PRODUCER_LIB_EXPORT MySecondNativeClass {
public:
MySecondNativeClass(int val);
int getValue() const;
private:
int m_value;
};
The .cpp file:
#include "stdafx.h"
#include "MySecondNativeClass.h"
MySecondNativeClass::MySecondNativeClass(int val) {
this->m_value = val;
}
int MySecondNativeClass::getValue() const {
return this->m_value;
}
Using this class in the same project works fine, but using it in another (C++/CLI) project gives me "unresolved external symbol" linker errors. (COMPILE_PRODUCER_LIB is a preprocessor definition defined only in the project that contains the class.)
I've created a small solution (for Visual Studio 2010) that shows the problem (download at the end of this page). There, the native class MySecondNativeClass is defined in the project "ManagedProviderLib" and is being used in "ExternalTestClass.cpp" (in project "ManagedExternalLib").
Your DLL project creates a .lib file in the build directory, the DLL's import library. You need to specify that .lib file in the other project, Linker + Input, Additional Dependencies setting.
Note that Add Reference cannot work, the assembly metadata only contains definitions for managed classes. Your class is native C++, not managed. Also make sure that your .cpp file is compiled without /clr in effect. The C++/CLI compiler will happily translate native C++ classes to IL but that is not very efficient. You can control this within the source code file with #pragma managed.

call unmanaged C++ code from C# using pinvoke

I have a unmanaged C++ dll for which I do not have access to code but have all methods declarations for.
Lets for simplicity say that .h looks like this:
#include <iostream>
#ifndef NUMERIC_LIBRARY
#define NUMERIC_LIBRARY
class Numeric
{
public:
Numeric();
int Add(int a, int b);
~Numeric();
};
#endif
and method implementation in .cpp file
int Numeric::Add(int a, int b)
{
return (a + b);
}
I simply want to call the add function from C++ in my C# code:
namespace UnmanagedTester
{
class Program
{
[DllImport(#"C:\CPP and CSharp Project\UnmanagedNumeric\Debug\numeric.dll", EntryPoint = "Add")]
public static extern int Add(int a, int b);
static void Main(string[] args)
{
int sum = Add(2, 3);
Console.WriteLine(sum);
}
}
}
After trying to execute I have the following error:
Unable to find an entry point named 'Add' in DLL 'C:\CPP and CSharp Project\UnmanagedNumeric\Debug\numeric.dll'.
I CAN NOT change C++ code. Have no idea what is going wrong.
Appreciate your help.
Using PInvoke you can only call global functions exported from Dll. To use exported C++ classes, you need to write C++/CLI wrapper. This is C++/CLI Class Library project, which exposes pure .NET interface, internally it is linked to unmanaged C++ Dll, instantiates a class from this Dll and calls its methods.
Edit: you can start from this: http://www.codeproject.com/KB/mcpp/quickcppcli.aspx#A8
If you need to create a wrapper, take a look at swig.org. It will generate one for most high level language like C#.
I just came across this program a few minutes ago while working the same problem that you are.
To use a class from native C++ from C# you need a C++/CLi wrapper in between, as mentioned by by previous answers. To actually do that, it is not very straight forward. Here is I link that tell you how to do it at a high level: C++/CLI wrapper for native C++ to use as reference in C#.
If you are quite new to this (like me), you might stumble on 1) -- the linking part. To solve that, you can see how I did here (see my question portion): Link error linking from managed to unmanaged C++ despite linking to .lib file with exported symbols

Code injection - Solaris & Linux

I have an executable module created by third party. I would like to "inject" my code (kind of watchdog running in separate thread) into this process.
So far there are two possible ways - one is to run my code as executable and dynamically load a proess on top of it (seems to be very hard and tricky) or to make my code a shared object, load it via LD_PRELOAD and initialize from some static variable constructor.
Are there more convenient ways to do this ?
My OS are Linux x86 and Solaris-SPARC.
Update: If possible, I'd like not to patch the process, but load my code dynamicaly.
Sounds like you're looking for InjectSo. There's a Powerpoint presentation that explains how it works. I haven't gotten around to trying it out yet.
Hotpatch should do this for you. It is more capable than injectso.
Rob Kennedy told you about InjectSo - that's probably what you need.
Beware that the introduction of a thread into a non-threaded process would be fraught with synchronization issues. The problems are less serious if the application is already threaded, but even so, the application may object to a thread that it doesn't know about.
I have not used the mentioned InjectSo but it is a noteworthy information.
If you are looking for alternatives here is a simple way to inject your code:
#include <stdio.h>
#include <sys/types.h>
#include <pwd.h>
int main()
{
struct passwd* pswd = getpwuid(1000);
if(pswd)
printf("%s\n", pswd->pw_name);
return 0;
}
gcc test.c -o test
#define _GNU_SOURCE
#include <dlfcn.h>
#include <sys/types.h>
#include <pwd.h>
#include <stdlib.h>
#include <stdio.h>
static char* hocus = "hocus pocus";
struct passwd *getpwuid(uid_t uid)
{
static struct passwd *(*orig_getpwuid)(uid_t uid);
if(!orig_getpwuid) {
orig_getpwuid = (struct passwd* (*)(uid_t))dlsym(RTLD_NEXT, "getpwuid");
}
struct passwd* original_passwd = (*orig_getpwuid)(uid);
if(original_passwd) {
original_passwd->pw_name = hocus;
}
// your code here
return original_passwd;
}
gcc inject.c -shared -o libinject.so
run with LD_LIBRARY_PATH=. LD_PRELOAD=libinject.so ./test
Should say hocus pocus. You can override arbitrary libc functions, like printf, snprintf - just find what is that module using.
In the "your code here" you can start arbitrary threads, watchdogs etc.

Resources