So I try to port some Boost.Extension samples for linux.
The sample is described here. Here is my code port (classes with animals, animal prototype, main app, general all port idea is described here, and some current linux progress here (some samples really work as needed!)). When I compile this sample under linux it compiles, it finds library with animals but outputs:
Animals not found!
Which shall happen only if(factories.empty()).
I try to port Extension samples onto crossplatform base - so I have tried same code under windows - works like a charm! finds all animals and outputs:
Creating an animal using factory:
Cougar factory Created an animal:
cougar Age: 2 Creating an animal using
factory: Leopard factory Created an
animal: leopard Age: 3 Creating an
animal using factory: Puma factory
Created an animal: puma Age: 4
Creating an animal using factory:
Wildcat factory Created an animal:
wildcat Age: 5
So... Why it behaves so on linux with same code? Why it works so well under Windows?
Update:
So how to build this stuff with premake:
You get svn from here (only this folder is required)
You get premake for your platform or build it from source and put it into folder you downloaded from svn
You should have official Boost compiled and installed (please read ReadMe.txt file we provide in directory) so what is needed:
Boost C++ library's (we tested with version 1.4.16)
Boost-Extension ( we use latest revision , we adress it as part of boost 'boost/extension/**' We had to make some chandes (actually only one) to boost extension so we provide it inside Boost.Extension.Tutorial/libs/boost/extension/ folder so when you downloaded svn you got it, it is header only )
Boost-Reflection ( we use it because of this tutorial , we use latest revision , we adress it as part of boost 'boost/reflection/**' *and for simplness we recommend just to put it into Boost.Extension.Tutorial/libs/boost/reflection * )
Now when official Boost is in your system, header only Boost-reflection and Boost-extension are in Boost.Extension.Tutorial/libs/boost folder, premake4 executable is inside Boost.Extension.Tutorial/ folder we can simply call Boost.Extension.Tutorial/ premake4-build-windows.bat on windows to get sln for Visual Studio or Boost.Extension.Tutorial/ premake-build.sh to get makefiles.
You can find generated solution/makefiles inside generated projects folder.
Have good luck!=)
Update 2:
Project files for Windows and Linux are now in svn so you can get aroung project creation with premake - just have Boost, our svn, and reflection headers only lib.
I debugged things on linux, good news:
You are running into bullet no. 3 from Jeremy Pack's post:
RTTI does not always function as expected across DLL boundaries. Check out the type_info classes to see how I deal with that.
I have a tiny workaround patch (below) to boost/extension/impl/typeinfo.hpp (but you need to talk to the maintainer of Boost Extension, really). What this does is not rely on builtin comparison for RTTI typeinfo's.
Looking at typeinfo.hpp, it seems that Windows never actually uses the typeinfo comparison, so I decided to test with the 'strcmp' fallback method, and voila:
$ LD_LIBRARY_PATH=. ./Simple-Inheritance
Creating an animal using factory: Cougar factory
Created an animal: cougar Age: 2
Creating an animal using factory: Leopard factory
Created an animal: leopard Age: 3
Creating an animal using factory: Puma factory
Created an animal: puma Age: 4
Creating an animal using factory: Wildcat factory
Created an animal: wildcat Age: 5
In particular, I can show that the type lookup from convertible_ fails at type_map.hpp, line 68;
When this conversion is called from the extension dll itself, the conversion happily finds the match using RTTI.
However, when the 'same' .get() is done from the test application (across DLL boundaries, i.e.) the RTTI is different and no such match is found, and line 74/75 are hit:
.
73 if (it == instances_.end()) {
74 holder = new type_holder<StoredType>;
75 it = instances_.insert(std::make_pair(t, holder)).first;
76 }
Patch
diff --git a/Boost.Extension.Tutorial/libs/boost/extension/impl/typeinfo.hpp b/Boost.Extension.Tutorial/libs/boost/extension/impl/typeinfo.hpp
index 843fed2..09fc353 100644
--- a/Boost.Extension.Tutorial/libs/boost/extension/impl/typeinfo.hpp
+++ b/Boost.Extension.Tutorial/libs/boost/extension/impl/typeinfo.hpp
## -50,7 +50,7 ## struct type_info_handler<default_type_info, ClassType>
// This list should be expanded to all platforms that successfully
// compare type_info across shared library boundaries.
-#if defined(__APPLE__) || defined(__GNUC__) || \
+#if defined(__APPLE__) || \
defined(BOOST_EXTENSION_FORCE_FAST_TYPEINFO)
namespace boost {
namespace extensions {
## -90,7 +90,7 ## inline bool operator>(const default_type_info& first,
} // namespace extensions
} // namespace boost
#else // OTHER OS
-#include <string>
+#include <cstring>
namespace boost { namespace extensions {
inline bool operator<(const default_type_info& first,
const default_type_info& second) {
GCC on Linux by default has stricter linker optimization settings that MSVC on Windows. This leads to some factory patterns where classes register themselves as available appearing broken, simply because the linker optimizes away the classes. I didn't look at your code - but from the description it could be the problem.
A related question, with an answer on how to avoid the unreferenced classes being dropped: How to force gcc to link unreferenced, static C++ objects from a library
Related
I want to run my C++ code no micropython
For that I referred https://github.com/stinos/micropython-wrap this wrapper.
Uploaded required wrapper files on the board and tried to run
#include <micropython-wrap-master/functionwrapper.h>
//function we want to call from within a MicroPython script
std::vector< std::string > FunctionToBeCalled ( std::vector< std::string > vec )
{
for( auto& v : vec )
v += "TRANSFORM";
return vec;
}
//function names are declared in structs
struct CppFunction
{
func_name_def( TransformList )
};
extern "C"
{
void RegisterMyModule(void)
{
//register a module named 'foo'
auto mod = upywrap::CreateModule( "foo" );
//register our function with the name 'TransformList'
//conversion of a MicroPython list of strings is done automatically
upywrap::FunctionWrapper wrapfunc( mod );
wrapfunc.Def< CppFunction::TransformList >( FunctionToBeCalled );
}
}
Run it using
import foo
print(foo.TransformList(['a', 'b'])) # Prints ['aTRANSFORM', 'bTRANSFORM']
But later I found this will not help. Because I need to integrate my C++ code into micropython code and rebuild the firmware to get it run.
I am not able to figure out
How to integrate my C++ in existing micropython code
How to recompile the firmware ( Because when I try to use make command, it does not seem working )
Any help highly appreciated.
MicroPython offers two options of adding C/C++ code to it.
Note that both require cross-compilation of that code on a PC.
AFAIK there is no option to compile on a microcontroller (due to obvious constraints)
1) MicroPython Native Module
One of the main advantages of using native .mpy files is that native machine code can be imported by a script dynamically, without the need to rebuild the main MicroPython firmware.
Essentially you compile C to MicroPython bytecode and store that in a module.
Then you import that module into Python
http://docs.micropython.org/en/latest/develop/natmod.html#minimal-example
2) MicroPython C Module
You add you C/C++ code as a custom module, and then compile and link that together into a new firmware image.
http://docs.micropython.org/en/latest/develop/cmodules.html#micropython-external-c-modules
The approach you refer to, is based on the 2nd method, and requires cross-compilation.
C or C++ support will depend on the compiler/languages supported for you port/hardware.
You don't need necessarily need to recompile, you can build a C++ user module. Which has been done for ESP32 already, see discussion at https://github.com/stinos/micropython-wrap/issues/5#issuecomment-704328111.
Specifically if you run make USER_C_MODULES=../../../micropython-wrap CFLAGS_EXTRA="-DMODULE_UPYWRAPTEST_ENABLED=1" from the ESP32 port directory, this should build a user C++ module containing micropython-wrap's unittests, so that should be a good starting point: copy the relevant files (cmodule.c, module.cpp and micropython.mk from the tests directory) and modify the code.
As the title says, I can't create a simple DLL. I'm using VS 2017 Community Edition Version 15.8.0. Here is the .dll code:
#include "stdafx.h"
#include "InvWin32App.h"
#include "$StdHdr.h"
void Prc1()
{
printf("ran procedure 1\n");
}
Here is the code for the header, per the MS way to do things:
#ifdef INVWIN32APP_EXPORTS
#define INVWIN32APP_API __declspec(dllexport)
#else
#define INVWIN32APP_API __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C" {
#endif
INVWIN32APP_API void Prc1();
#ifdef __cplusplus
}
#endif
Here is the driver code: (Update: The driver program is an .exe program.)
#include "pch.h"
#include "InvWin32App.h"
int main()
{
Prc1();
}
It can't get any simpler than this. I get the following error message box when I try to run the code:
Unable to start program
program name.dll
program name.dll is not
a valid Win32 application
I can create .exe programs okay. I also got the error earlier this morning when I was running VS 2017 Version 15.7.5. Upgrading VS didn't do any good. I also tried to compile these as .c programs, but it didn't make any difference.
I had this problem on a couple occasions creating .exe programs using VS 2015. I don't recall what I did, but the problem disappeared. Any help would be appreciated.
TIA.
Right click the project in your solution explorer that is the project for the executable and click "Set as startup project."
Note that "is not a valid Win32 application" is not a compile error or a link error, it is the message you get when you tried to debug something that is not executable.
You can only start executables. Executables consume dlls. These should be two seperate projects with two sets of corresponding project settings.
I doubt that you are using a 32 bit dll. If you have your 64-bit Windows OS then you must have 64 bit version of this dll too. Sometimes, even you have 64-bit dll already then it could not run, so try the other version of this dll i.e. 32 bit version of this dll.
Along with this, make a small change in your unicurse.py file too.
PFB the code to add:
import ctypes
pdlib = ctypes.CDLL("pdcurses.dll")
though this line of code is somewhere inside some condition, but bringing on top will help you to check, if the dll has been loaded or not.
For any one joining the party at this time, I found that this error is caused when you try to run a 32bit dll using a 64bit python.
Now I won't go into the details as to why that won't work as above responses clearly describes that, but there are 2 solutions for this.
Install and 32bit python and use that to communicate with the dll.
Interprocess communication using the msl-loadlib library documentation
I used the second step which seemed more sustainable. The steps I am using below can be found in the documentation link above.
First is to create a server module that communicates with the 32 bit module
#server.py
from msl.loadlib import Server32
class Server(Server32):
# the init takes mandatory host and port as arguments
def __init__(self, host, port, **kwargs):
# using windll since this application is being run in windows, other options such as cdll exists
# this assumes that the dll file is in the same directory as this file
super(Server, self).__init__('tresdlib.dll', 'windll', host, port)
# define a function that is to be called with the required arguments
def fsl_command(self, com, doc):
#the server32 exposes the loaded dll as lib, which you can then use to call the dll functions and pass the required arguments
return self.lib.FSL_Command(com,doc)
Then we create a client module, that sends python requests to the server module
#client.py
from msl.loadlib import Client64
class Client(Client64):
def __init__(self):
# pass the server file we just created in module32=, the host am using is localhost, leave port as none for self assigning
super(Client, self).__init__(module32='server', host="127.0.0.1", port=None)
# define a function that calls the an existing server function and passes the args
def fsl_command(self, com, doc):
return self.request32('fsl_command', com, doc)
We are going to run this in a terminal but you can choose to call in another application
>>> from client import Client
>>> c = Client()
>>> c.fsl_command(arg1,arg2)
I'm trying to use Eclipse to do the development for a project that involves Gazebo (a popular robotics simulator). Gazebo provides a plugin system to allow external interaction with the simulator and a series of tutorials on how to write plugins.
Having followed the tutorials successfully, I tried migrating the code to Eclipse, using cmake -G "Eclipse CDT4 - Unix Makefiles" [buildpath] to generate an eclipse rpoject, then importing it into my Eclipse workspace.
Everything generally went well, but I've run into a problem that is a bit odd:
When I compile my project, Eclipse comes back with "Member declaration not found" error referring to an SDFormat data type used in the signature to the ModelPush::Load function (see code snippets below). SDFormat, incidnetally is a robotics XML used for describing how a robot is put together.
Despite this error (which should result in nothing being built), the resulting shared library is built anyway.
I guess I can live with it, but I'd obviously like to resolve this issue, which appears to be internal to Eclipse / CDT...
TO CLARIFY:
I'm trying to determine why Eclipse gives me the error: "Member declaration not found" on the Load() function signature in model_push.cc. The guilty party is the sdf::ElementPtr _sdf parameter. Something's wrong with the SDFormat library or with the way that Eclipse / CDT looks at it. This isn't an include issue. And, even though Eclipse gives me the error, it still builds the .so file. Running make from the command line also generates the file, but without any errors.
Again, I can live with it, but I'd rather not. I just don't know where to start looking for a solution since this isn't a problem finding an include or the sdf library file.
Here's the class declaration (mode_push.hh):
#ifndef MODEL_PUSH_HH_
#define MODEL_PUSH_HH_
#include <boost/bind.hpp>
#include <gazebo/gazebo.hh>
#include <gazebo/physics/physics.hh>
#include <gazebo/common/common.hh>
#include <stdio.h>
#include <sdf/sdf.hh>
namespace gazebo
{
class ModelPush : public ModelPlugin
{
public:
void Load (physics::ModelPtr _parent, sdf::ElementPtr _sdf);
//Called by the world update start event
void OnUpdate (const common::UpdateInfo & /*_info*/);
//Pointer to the model
private:
physics::ModelPtr model;
//Pointer to the update event connection
private:
event::ConnectionPtr updateConnection;
};
}
#endif /* MODEL_PUSH_HH_ */
Here's the implementation file (model_push.cc):
#include "model_push.hh"
namespace gazebo
{
void ModelPush::Load(physics::ModelPtr _parent, sdf::ElementPtr _sdf)
//void ModelPush::Load (physics::ModelPtr _parent, sdf::ElementPtr /*sdf*/)
{
//Store the pointer to the model
this -> model = _parent;
//Listen to the update event. This event is broadcast every
//simulation iteration.
this -> updateConnection = event::Events::ConnectWorldUpdateBegin(
boost::bind (&ModelPush::OnUpdate, this, _1));
}
//Called by the world update start event
void ModelPush::OnUpdate (const common::UpdateInfo & /*_info*/)
{
//Apply a small linear velocity to the model.
this -> model -> SetLinearVel (math::Vector3 (0.03, 0.0, 0.0));
}
//Register this plugin with the simulator
//GZ_REGISTER_MODEL_PLUGIN(ModelPush)
}
I've been struggling with this exact problem. I've found a solution that works, but I still don't think is ideal. Instead of generating the eclipse project using cmake (or catkin_make) I'm generating it using the CDT project builder. Here's the process I'm using in Eclipse 2018-09.
Create a New C/C++ Project of type C++ Managed Build (A C++ Project build using the CDT's managed build system.)
Project name: ROSWorkspace
Location: /home/username/eclipse-workspace/ROSWorkspace
Project type: Makefile project / Empty Project
Toolchain: Linux GCC
Finish.
Right click on the project and select Properties.
C/C++ Build / Builder Stetings:
Uncheck "Use default build command"
Build command: catkin_make
Build directory: ${workspace_loc:/../catkin_ws}/
C/C++ General / Paths and Symbols / Includes tab
Add /usr/include/gazebo-8
Add /usr/include/sdformat-5.3
C/C++ General / Preprocessor Includes / Providers tab
CDT GCC Built-in Compiler Settings / Command to get compiler specs: ${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}" -std=c++11
Click Ok, then from the drop down menu choose:
Project / C/C++ Index / Freshen all files
Ideally I'd make the time to dig in to figure out how to get the preprocessor to properly work with the generated project, but I just don't have the time right now. I hope this helps.
I've just finished following the "Getting Started" instructions from the clang analyzer page.
My XCode is currently using the checker build 278
Right now I'm trying to follow some guides I can find to write my own custom checkers like
http://blog.trailofbits.com/2014/04/27/using-static-analysis-and-clang-to-find-heartbleed/
http://bbannier.github.io/blog/2015/05/02/Writing-a-basic-clang-static-analysis-check.html
Was hoping that someone can point me in the right direction and I'm not very familiar with building clang projects.
Are there any IDE available that would help?
How should I add the custom checker I wrote to the build 278?
I have recently started using clang checker's and here's how I got my custom checker to work with clang.
You have to modify the Checkers.td to register your checker.
<path-to-llvm>/llvm/tools/clang/lib/StaticAnalyzer/Checkers/Checkers.td
I made a debug checker to I put it under debug group and added these lines:
def MyCustomChecker : Checker<"DebugUsingMyChecker">,
HelpText<"Print results of my custom checker">,
DescFile<"DebugCheckers.cpp">; //this is the file where we define the class file of our checker
Then edit the DebugCheckers.cpp to add your checker's class to be invoked by the newly registered checker.
<path-to-llvm>/llvm/tools/clang/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp
And add under debug checkers tag
namespace
{
class MyCustomChecker : public Checker<check::ASTCodeBody> {
public:
void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
BugReporter &BR) const {
if (MyCustomChecker* CC = mgr.getAnalysis<CustomChecker>(D)) {
CC->dump(mgr.getSourceManager());
}
}
};
}
void ento::registerMyCustomChecker(CheckerManager &mgr) {
mgr.registerChecker<MyCustomChecker>();
}
After this, you can place the relevant class files in the folder:
<path-to-llvm>/llvm/tools/clang/lib/Analysis/
And edit the CMakeList.txt in that folder to include your class file.
Hope that clarifies the process. You can also read this link for more: http://clang-analyzer.llvm.org/checker_dev_manual.html
As far as IDE's are concerned, you can use any IDE which supports's CMake based projects (like CLion). You can look at this link for more: http://llvm.org/docs/CMake.html
I just upgraded to Mac OSX 10.7 Lion. First of all, I hate the new spaces, I dislike not being able to access any directories deeper than my user directory, but lets get to the question.
I develop Audio Unit Plugins. I have a few whose code is compiling and working perfectly (they're even released for sale) in XCode 4.0.
But after upgrading to Lion and XCode 4.1, there are now two major compiling failures in the main audio unit .cpp file (mine is named TestAU.cpp) where the Process method resides. Below is the code that fails.
#include "TestAU.h"
COMPONENT_ENTRY(TestAU) // FAIL c++ requires a type specifier for all declarations.
TestAU::TestAU(AudioUnit component) : AUEffectBase(component) // FAIL Expected ';' after top level declarator.
{
CreateElements();
Globals()->UseIndexedParameters(kNumberOfParameters);
SetParameter(kParam_One, kDefaultValue_ParamOne );
#if AU_DEBUG_DISPATCHER
mDebugDispatcher = new AUDebugDispatcher (this);
#endif
}
I'm having trouble solving this failure. Any help would be great. Thanks.
Search in the Xcode documentation for Technical Note TN2276 for instructions on updating an existing audio unit for Lion.
You have to replace
COMPONENT_ENTRY(TestAU)
with
AUDIOCOMPONENT_ENTRY(TestAU, Filter)
But there is a little more so read the document.
Edit:
BTW regarding your comment about not being able to access all directories you can find many locations in the Go menu of finder.