Hallo fellow members,
I run into a very strange problem today and I am not exactly sure as to what is causing it. Here is a function which I use to get the current working directory :
#ifdef _WIN32
#include <direct.h>
#define GetCurrentDir _getcwd
#else
#error "There is currently no support for non windows based systems!"
#endif
const std::string getCurrentPath()
{
char CurrentPath{_MAX_PATH];
GetCurrentDir(CurrentPath, _MAX_PATH);
CurrentPath[_MAX_PATH - 1] = '/0';
return std::string(CurrentPath);
}
This function works well as a stand alone function. However if I declare it as a static function inside a class :
static __declspec(dllexport) const std::string getCurrentPath(void);
and a .dll I get "debug assertion failed error" when I try to do
std::cout<<CUtilities::getCurrentPath()<<std::endl;
If I instead write :
std::string dir = CUtilities::getCurrentPath();
std::cout<<"Dir is : "<<dir<<std::endl;
it works fine. I am totally confused as to what I am doing wrong. Any ideas?
I finally found out what the problem was. The project was compiled with /MT options , therefore the .dll had a different heap than the original file. So when the string size was bigger than it's initial size (15) then heap was allocated from the .dll's side. However the string had it's destructor called from the main program side and then the destructor was trying to deallocate memory from the .dll's heap thus resulting in "heap corruption error"
The solution was to simply compile with /MD options.
Related
In the journey to learning C++ im learning through the C++ Manual thats on the actual website. Im using DevC++ and have hit a problem, not knowing whether its the compilers error or not.
I was going through this code bit by bit typing it in myself, as I feel its more productive, and adding my own stuff that ive learnt to the examples, then I get to initialising variables. This is the code that is in the C++ manual
#include <iostream>
using namespace std;
int main ()
{
int a=5; // initial value = 5
int b(2); // initial value = 2
int result; // initial value undetermined
a = a + 3;
result = a - b;
cout << result;
return 0;
}
This is popping up a compiler error saying " Multiple definitions of "Main""
Now This is on the actual C++ page so im guessing its a compiler error.
Could someone please point me in the right direction as to why this is happening and what is the cause for this error.
Multiple definitions of "main" suggests that you have another definition of main. Perhaps in another .c or .cpp file in your project. You can only have one function with the same name and signature (parameter types). Also, main is very special so you can only have one main function that can be used as the entry point (has either no parameters, one int, or an int and a char**) in your project.
P.S. Technically this is a linker error. It's a subtle difference, but basically it's complaining that the linker can't determine which function should be the entry point, because there's more than one definition with the same name.
Found I had two file references in my tasks.json file that were causing this error and which took me a long time to figure out. Hope this helps someone else..... See "HERE*****" below:
"-I/usr/include/glib-2.0",
"-I/usr/lib/x86_64-linux-gnu/glib-2.0/include",
//"${file}", //HERE**********************
"-lgtk-3",
"-lgdk-3",
"-lpangocairo-1.0",
"-lpango-1.0",
"-lharfbuzz",
"-latk-1.0",
"-lcairo-gobject",
"-lcairo",
"-lgdk_pixbuf-2.0",
"-lgio-2.0",
"-lgobject-2.0",
"-lglib-2.0",
"-o",
"${fileDirname}/${fileBasenameNoExtension}" //HERE*************
],
When I practiced CMake, I encountered the same problem. Finally, I found that the source code path set in the cmakelist project was incorrect. As a result, the compiled files included many duplicate files generated during CMake execution. As a result, compilation errors occurred
I'm currently porting a large project to Atmel Studio from ICCAVR as I need to use some of the ASF libraries for the project I'm working on.
I'm getting this error with the code example below in regards to trying to convert the following line to Atmel Studio
void debugoutf(__flash char * header, __flash char * msg);
Error pointer targeting address space '__flash' must be const in
function parameter 'header'
I tried using the macro in the documentation so that it can compile in Atmel Studio.
#ifndef FLASHVAR_H_
#define FLASHVAR_H_
#include <avr/pgmspace.h>
#if defined(__ICCAVR__) // IAR C Compiler
#define FLASH_DECLARE(x) __flash x
#endif
#if defined(__GNUC__) // GNU Compiler
#define FLASH_DECLARE(x) x __attribute__((__progmem__))
#endif
IAR to AVR Conversion
void debugout(FLASH_DECLARE (char * header), char * msg);
My question is have I done the conversion correctly, as I don't think I've done it correctly as nothing is getting printed out in my UART debugging.
The problem with using __attribute__((__progmem__)) on a variable is that whenever you want to read data from such a variable, you can't just access it in the usual way that you would access a variable from RAM. Instead, you have to use special functions provided by the avr/pgmspace.h header in avr-libc, like pgm_read_byte.
That's pretty annoying, but you don't have to do it that way because why they added named address spaces like __flash to recent versions of GCC (assuming you are using C, not C++). I recommend you stop using __attribute__((__progmem__)) and use __flash instead, if your version of GCC supports it. If the compiler gives you an error or warning because it expects items stored in flash to be marked as const, you can simply add const to the declaration/definition (in the right position). If you have trouble doing that, please post a new question or edit this question so it contains a MCVE.
For the example code you gave, you should try writing:
void debugoutf(const __flash char * header, const __flash char * msg);
We have a plugin system that calls functions in dlls (user-generated plugins) by dlopening/LoadLibrarying the dll/so/dylib and then dlsyming/GetProcAddressing the function, and then storing that result in a function pointer.
Unfortunately, due to some bad example code being copy-pasted, some of these dlls in the wild do not have the correct function signature, and do not contain a return statement.
A dll might contain this:
extern "C" void Foo() { stuffWithNoReturn(); } // copy-paste from bad code
or it might contain this:
extern "C" int Foo() { doStuff(); return 1; } // good code
The application that loads the dll relies on the return value, but there are a nontrivial number of dlls out there that don't have the return statement. I am trying to detect this situation, and warn the user about the problem with his plugin.
This naive code should explain what I'm trying to do:
typedef int (*Foo_f)(void);
Foo_f func = (Foo_f)getFromDll(); // does dlsym or GetProcAddress depending on platform
int canary = 0x42424242;
canary = (*func)();
if (canary == 0x42424242)
printf("You idiot, this is the wrong signature!!!\n");
else
real_return_value = canary;
This unfortunately does not work, canary contains a random value after calling a dll that has the known defect. I naively assumed calling a function with no return statement would leave the canary intact, but it doesn't.
My next idea was to write a little bit of inline assembler to call the function, and check the eax register upon return, but Visual Studio 2015 doesn't allow __asm() in x64 code anymore.
I know there is no standards-conform solution to this, as casting the function pointer to the wrong type is of course undefined behavior. But if someone has a solution that works at least on 64bit Windows with Visual C++, or a solution that works with clang on MacOS, I would be most delighted.
#Lorinczy Zsigmond is right in that the contents of the register are undefined if the function does something but returns nothing.
We found however that in practice, the plugins that return nothing also have almost always empty functions that compile to a retn 0x0 and leaves the return register untouched. We can detect this case by spraying the rax register with a known value (0xdeadbeef) and checking for that.
I have a need to compile an existing message library generated using ZeroC's ICE with c++ clr.
I've been at this for a while and I'm having no luck.
I have a very simple .ice message file defined.
Upon generating the cpp and h files for this, I try to compile them into a .dll.
My slice2cpp command line args are
C:\Program Files (x86)\ZeroC\Ice-3.5.1\bin\slice2cpp.exe --depend --dll-export=ENABLE_DLL -I"C:\Program Files (x86)\ZeroC\Ice-3.5.1\slice" -I".\.." --underscore "E:\test\platform\platform\testMessage.ice"
This generates me a testMessage.cpp and testMessage.h files.
Upon attempting to compile these, I get the error:
Error 7 error LNK2028: unresolved token (0A00098D) "class IceUtil::Shared * __cdecl IceInternal::upCast(class IceInternal::ObjectFactoryManager *)" (?upCast#IceInternal##$$FYAPEAVShared#IceUtil##PEAVObjectFactoryManager#1##Z) referenced in function "public: __cdecl IceInternal::Handle<class IceInternal::ObjectFactoryManager>::Handle<class IceInternal::ObjectFactoryManager>(class IceInternal::Handle<class IceInternal::ObjectFactoryManager> const &)" (??0?$Handle#VObjectFactoryManager#IceInternal###IceInternal##$$FQEAA#AEBV01##Z) E:\test\platform\platform\testMessage.obj platform
As per usual with Ice, I have to link the Iced.lib and IceUtild.lib files.
I compile with no pre compiled headers and /clr option on (not pure clr or safe)
using VS2013. The body of the testMessage.ice file is very simple.
#ifndef _MESSAGE_ICE_
#define _MESSAGE_ICE_
module messaging {
class Message
{
string clientId;
string origin;
string destination;
string messageType;
string suffix;
};
sequence<Message> MessageSeq;
class NonQueuedMsg extends messaging::Message {};
};
#endif
Compiling without the CLR option on results in success.
I imagine this is all caused by my lack of familiarity with c++ clr.
Any help would be appreciated.
I had the same problem after the migration of my projects to vs 2013.
The project c++ with ice compile fine
but the project c++/cli with ice don't links.
I fixed linking problem in ObjectFactoryManagerF.h :
#ifdef __cplusplus_cli
IceUtil::Shared* upCast(ObjectFactoryManager* p) { return (IceUtil::Shared*) p; };
#else
IceUtil::Shared* upCast(ObjectFactoryManager* );
#endif
I stopped trying to make C++/CLI and ICE-generated code work together after I read on their forum here that they didn't support it.
What I've done.. I've made native static library on the client's side where I had C++/CLI. Static library fully encapsulated all communication stuff and was referenced from C++/CLI part. As a result I've got a Mixed (C++/CLR) Recommended Rules assembly. It works fine plus I've got easier portable application.
I have an existing project, originally implemented as a Vxworks 5.5 style kernel module.
This project creates many tasks that act as a "host" to run external code. We do something like this:
void loadAndRun(char* file, char* function)
{
//load the module
int fd = open (file, O_RDONLY,0644);
loadModule(fdx, LOAD_ALL_SYMBOLS);
SYM_TYPE type;
FUNCPTR func;
symFindByName(sysSymTbl, &function , (char**) &func, &type);
while (true)
{
func();
}
}
This all works a dream, however, the functions that get called are non-reentrant, with global data all over the place etc. We have a new requirement to be able to run multiple instances of these external modules, and my obvious first thought is to use vxworks RTP to provide memory isolation.
However, no matter what I try, I cannot persuade my new RTP project to compile and link.
error: 'sysSymTbl' undeclared (first use in this function)
If I add the correct include:
#include <sysSymTbl.h>
I get:
error: sysSymTbl.h: No such file or directory
and if i just define it extern:
extern SYMTAB_ID sysSymTbl;
i get:
error: undefined reference to `sysSymTbl'
I havent even begun to start trying to stitch in the actual module load code, at the moment I just want to get the symbol lookup working.
So, is the system symbol table accessible from VxWorks RTP applications? Can moduleLoad be used?
EDIT
It appears that what I am trying to do is covered by the Application Programmers Guide in the section on Plugins (section 4.9 for V6.8) (thanks #nos), which is to use dlopen() etc. Like this:
void * hdl= dlopen("pathname",RTLD_NOW);
FUNCPTR func = dlsym(hdl,"FunctionName");
func();
However, i still end up in linker-hell, even when i specify -Xbind-lazy -non-static to the compiler.
undefined reference to `_rtld_dlopen'
undefined reference to `_rtld_dlsym'
The problem here was that the documentation says to specify -Xbind-lazy and -non-static as compiler options. However, these should actually be added to the linker options.
libc.so.1 for the appropriate build target is then required on the target to satisfy the run-time link requirements.