dllwrap could not work with <iostream>? - c++

dllwrap is the tool of the GNU GCC in mingw .It be used to build .dll file like gcc or g++.but I found it did not work well with like below:
hello3.cpp
#include<iostream>
extern "C" void MyDllSay( void )
{
}
hello3.def
LIBRARY hello3.dll
EXPORTS
MyDllSay #1
hello = MyDllSay #2
the compiler code is
g++.exe -c -O3 hello3.cpp
dllwrap.exe -o hello3.dll hello3.o --def hello3.def --output-lib
libhello3.a
the error report is
hello3.o:hello3.cpp:(.text+0x8): undefined reference to
std::ios_base::Init::~I nit()'
hello3.o:hello3.cpp:(.text.startup+0xc): undefined reference to
std::ios_base:: Init::Init()' collect2.exe: error: ld returned 1 exit
status
if I set the hello3.cpp like this
//#include<iostream>
#include<fstream>
extern "C" void MyDllSay( void )
{
}
or like this
//#include<iostream>
extern "C" void MyDllSay( void )
{
}
everything is fine.
How to make dllwrap work with iostream?
Thanks a lot in advance for any help !

I just tested the a option in dllwrap .It worked well,I will check it further .
but i can't find the explaintion in dllwrap old wiki
the option is
-lstdc++
the new compiler is
dllwrap.exe -o hello3.dll hello3.o --def hello3.def --output-lib
libhello3.a -lstdc++

Related

Including files correctly , but still getting linker error

hope you guys are doing well. I am just getting linker error in C++ , I don't know why? Everything is correct....
Check below testing.h file
#ifndef __MYClass__
#define __MYClass__
#include<iostream>
using namespace std;
class Abc {
private:
int a;
public:
void input();
void display();
};
#endif
and here's implementation of these functions in Functions.cpp file.
#include"testing.h"
void Abc::input() {
cout<<"Enter any value : ";
cin>>a;
}
void Abc::display() {
cout<<"You Entered : "<<a;
}
And now, in main.cpp
#include<iostream>
#include"testing.h"
using namespace std;
int main() {
Abc obj;
obj.input();
obj.display();
return 0;
}
All files are compiled successfully.
In main.cpp Linker says....
g++ -Wall -o "main" "main.cpp" (in directory: /home/Welcome/C++ Practices/testingLinux)
/usr/bin/ld: /tmp/ccYI9LAy.o: in function main': main.cpp:(.text+0x10): undefined reference to Abc::input()'
/usr/bin/ld: main.cpp:(.text+0x1c): undefined reference to `Abc::display()'
collect2: error: ld returned 1 exit status
Compilation failed.
I'm using built-in linux compiler...
There are multiple ways you can fix this but before that please read up on Translation Unit.
Coming to your problem.
When you write
g++ -Wall -o main main.cpp
The compiler will pick up main.cpp for compilation and expand testing.h that includes the declaration for class ABC and with this header file it can determine what is the size of ABC and be able to generate instructions reserving space for obj on the stack. It can't see the definition for input() and display() hence defers that task to the linker. Note that testing.cpp is not in the picture at all since the compiler doesn't know that the implementation of ABC is in testing.cpp. Now when the linker tries to resolve the symbols input() it fails to find the definition for it and throws the error
undefined reference to Abc::input()
So, to fix this you can tell explicitly upfront that it also needs to take in testing.cpp while compiling main.cpp by
g++ -o main main.cpp testing.cpp
Another way is to create a dynamic library out of testing.h and testing.cpp
g++ -shared -fPIC testing.cpp -o libtest
and then link it against main.cpp
g++ -o main main.cpp -I. -L. libtest
What this does is that the compiler still can't figure out the definition of input() and display() but the linker can since now the library containing the definitions is provided to it.
You are not compiling Functions.cpp file.
This should fix your issue:
g++ main.cpp Functions.cpp

Error in MulVAL: multiple definition of `mylval'; collect2: error: ld returned 1 exit status

I'm getting this error while compiling MulVAL with "make" command on fedora OS.
This is the error:
multiple definition of `mylval'; lex.yy.o:/home/user/Desktop/mulval/src/attack_graph/graphit.l:5: first defined here
collect2: error: ld returned 1 exit status
make: *** [Makefile:4: attack_graph] Error 1
This is the Makefile I'm compiling:
default: install
attack_graph: attack_graph.cpp attack_graph.h Queue.h lex.yy.o y.tab.cpp
g++ -g -DLINUX -Wno-deprecated lex.yy.o y.tab.cpp attack_graph.cpp -o
attack_graph
lex.yy.c: graphit.l
lex -olex.yy.c graphit.l
lex.yy.o: lex.yy.c y.tab.cpp.h
gcc -g -c lex.yy.c -o lex.yy.o
y.tab.cpp y.tab.cpp.h: graphit.y attack_graph.h
bison -dv graphit.y
mv graphit.tab.c y.tab.cpp
mv graphit.tab.h y.tab.cpp.h
...
First few lines of graphit.y (showing where mylval is used):
#define YYSTYPE char *
extern YYSTYPE yylval;
extern "C"
{
int yyparse(void);
int yylex(void);
YYSTYPE* mylval = &yylval;
int yywrap()
{
return 1;
}
}
Few lines of graphit.l (also showing where mylval is used):
%{
#include <stdio.h>
#include "y.tab.cpp.h"
#define YYSTYPE char *
YYSTYPE* mylval;
FILE **my_ptr = &yyin;
%}
%%
...
[0-9]*\.[0-9]+ *mylval=(char *)strdup(yytext); return FLOAT;
[\.\[\]\,\(\)] return (int) yytext[0];
[\/a-zA-Z0-9_\-\+\.\=\\]+ *mylval=(char *)strdup(yytext); return ATOM;
...
%%
The full code can be found at https://github.com/fiware-cybercaptor/mulval
I tried to modify the graphit.y file by removing the YYSTYPE* before the mylval like this:
mylval = &yylval;
but it gave this error:
mylval does not name a type
which means that it's not defined before.
Please can anyone help?
I gather that you didn't write the program you're trying to compile, and I see that you filed some sort of bug report.
It's also evident that whoever did write the program had very little or no experience with flex or bison, and not much with C either. There are a great number of problems beyond the one which creates the compiler error you observed.
To fix the immediate error in graphit.l, change line 5 to:
extern YYSTYPE* mylval;
I don't believe that the variable is necessary at all; it looks to me like a clumsy solution to some Windows DLL problem. But removing the variable is more work than just making sure it has a single definition.

Building gcc plugin for windows on linux

Try to build the following gcc plugin on linux for windows with mingw cross compiler. The plugins are from the built avr compiler also for windows. Adapted the following plugin https://github.com/jcmvbkbc/avr-flash-vtbl.
#include <gcc-plugin.h>
#include <cp/cp-tree.h>
#ifdef _WIN32
__declspec(dllexport)
#endif
int plugin_is_GPL_compatible = 1;
void fn(void *gcc_data, void *user_data)
{
TYPE_ADDR_SPACE (TREE_TYPE (vtbl_type_node)) = 1;
TYPE_ADDR_SPACE (TREE_TYPE (vtbl_ptr_type_node)) = 1;
}
#ifdef _WIN32
__declspec(dllexport)
#endif
int plugin_init (struct plugin_name_args *plugin_info,
struct plugin_gcc_version *version)
{
register_callback("", PLUGIN_START_UNIT, fn, NULL);
return 0;
}
Output during compile and linking:
i686-w64-mingw32-g++ -shared -I/home/andreas/omgwtfbbq/win64/bin/../lib/gcc/avr/9.2.0/plugin/include -Wl,--export-all-symbols /home/andreas/
omgwtfbbq/win64/bin/../lib/gcc/avr/9.2.0/plugin/cc1plus.exe.a avr-flash-vtbl.c -o avr-flash-vtbl.so -I./
/usr/bin/i686-w64-mingw32-ld: /tmp/cc28ZVde.o:avr-flash-vtbl.c:(.text+0x4): undefined reference to `cp_global_trees'
/usr/bin/i686-w64-mingw32-ld: /tmp/cc28ZVde.o:avr-flash-vtbl.c:(.text+0x10): undefined reference to `cp_global_trees'
/usr/bin/i686-w64-mingw32-ld: /tmp/cc28ZVde.o:avr-flash-vtbl.c:(.text+0x44): undefined reference to `register_callback'
collect2: error: ld returned 1 exit status
make: *** [Makefile:11: avr-flash-vtbl.so] Fehler 1
The compiler flags are adapted from https://gcc.gnu.org/onlinedocs/gccint/Plugins-building.html. Has anybody already faced such a issue?
Problem is solved. Changed host compiler from i686-w64-mingw32-g++ to x86_64-w64-mingw32-g++ and changed the order of the options. /home/andreas/omgwtfbbq/win64/bin/../lib/gcc/avr/9.2.0/plugin/cc1plus.exe.a must go after avr-flash-vtbl.c.

undefined reference to `function_name'

I moved from Windows to Ubuntu and I wanted to try some C++ programming on Ubuntu. So here is very simple code and very stupid error which I can't resolve:
horse.h
#ifndef _horse_
#define _horse_
class Horse{
int speed;
public:
void saySomething();
};
#endif
horse.cpp
#include "horse.h"
#include <iostream>
using namespace std;
void Horse::saySomething(){
cout << "iiiihaaaaaaa brrrrr."<<endl;
}
and Main.cpp
#include "horse.h"
int main(){
Horse h;
h.saySomething();
}
After I compile (compilation is successful) and run this I get this error message:
/tmp/ccxuDyrd.o: In function `main':
Main.cpp:(.text+0x11): undefined reference to `Horse::saySomething()'
collect2: ld returned 1 exit status
Please help me somehow.
Try
g++ -c main.cpp horse.cpp (to compile)
g++ -o a.out main.o horse.o (to link)
It seems you only compiled your code but did not link the resulting object files. You probably invoked the compiler like this:
g++ main.cpp
You should instead compile every *.cpp file separately and then link each resulting *.o file. And you should do this with a Makefile.
Actually, the basic idea is the same on Windows with MSVC. The compiler produces object files, the linker links them together.

What's wrong withe following C code!

I tried the following code in C as well as C++ .file1 is a c file .file2 is a c++ file and file3 is a header file for name magling.
file1.c
#include<stdio.h>
#include<stdlib.h>
#include "file3.hpp"
int main(int argc,char **argv)
{
int a[5];
int i;
for(i=0;i<5;i++)
a[i] = i;
printf("%d",a[17]);
return 0;
}
file2.cpp
#include "file3.hpp"
int printtrial(int number)
{
return number;
}
file3.hpp
#ifdef __cplusplus
extern "C"
{
#endif
extern int printtrial(int number);
#ifdef __cplusplus
}
#endif
I compile it using the following commands:
gcc -c file1.c
g++ -c file2.cpp
gcc -o output file1.o file2.o
On this it gives the error:
file2.o:(.eh_frame+0x12): undefined reference to `__gxx_personality_v0'
collect2: ld returned 1 exit status
Can anyone tell me what's going on!
As one of your files is compiled as c++ use g++ for linking phase.
See: What is __gxx_personality_v0 for?
C and C++ executables require the presence of some libraries, which are included during the linking stage:
gcc -o output file1.o file2.o
The problem here is that you are trying to link a C++ file using a C linker. gcc simply fails to locate some libraries required by the C++ runtime. To solve this you must use g++, like yi_H said.