WxWidgets Symbol Resolving and Linking - linker

I'm trying to add GUI to my program using WxWidgets library. I also have a header file which I put all the #include statements there ("All_Headers.h").
I have added a header file which contains a simple WxFrame (Hello world like) into a header file ("GUI.h").
The problem is if I put (#include "GUI.h") in the All_Headers.h I get the following error:
(Kernel.obj and Crystall_Builder.obj are my object files)
1>Kernel.obj : error LNK2005: "protected: static struct wxEventTable const MyFrame::sm_eventTable" (?sm_eventTable#MyFrame##1UwxEventTable##B) already defined in Crystall_Builder.obj
1>Kernel.obj : error LNK2005: "protected: virtual struct wxEventTable const * __cdecl MyFrame::GetEventTable(void)const " (?GetEventTable#MyFrame##MEBAPEBUwxEventTable##XZ) already defined in Crystall_Builder.obj
1>Kernel.obj : error LNK2005: "protected: virtual class wxEventHashTable & __cdecl MyFrame::GetEventHashTable(void)const " (?GetEventHashTable#MyFrame##MEBAAEAVwxEventHashTable##XZ) already defined in Crystall_Builder.obj
1>Kernel.obj : error LNK2005: "public: __cdecl MyFrame::MyFrame(class wxString const &,class wxPoint const &,class wxSize const &)" (??0MyFrame##QEAA#AEBVwxString##AEBVwxPoint##AEBVwxSize###Z) already defined in Crystall_Builder.obj
1>Kernel.obj : error LNK2005: "public: void __cdecl MyFrame::OnQuit(class wxCommandEvent &)" (?OnQuit#MyFrame##QEAAXAEAVwxCommandEvent###Z) already defined in Crystall_Builder.obj
1>Kernel.obj : error LNK2005: "public: void __cdecl MyFrame::OnAbout(class wxCommandEvent &)" (?OnAbout#MyFrame##QEAAXAEAVwxCommandEvent###Z) already defined in Crystall_Builder.obj
However if I put (#include "GUI.h") in the Main file (Kernel.cpp) it works fine!
I don't have any Idea how I can find the origin of this error, please help.
Many Thanks
Main file (Kernel.cpp)
// #include "GUI.h" // If I put GUI.h in here it works fine
#include "All_Headers.h"
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit()
{
MyFrame *frame = new MyFrame( "Hello World",
wxPoint(50,50), wxSize(450,340) );
frame->Show(TRUE);
SetTopWindow(frame);
return TRUE;
}
GUI.h:
#ifndef GUI_H
#define GUI_H
#include "wx/wx.h"
class MyApp: public wxApp
{
virtual bool OnInit();
};
class MyFrame: public wxFrame
{
public:
MyFrame(const wxString& title,
const wxPoint& pos, const wxSize& size);
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
DECLARE_EVENT_TABLE()
};
enum
{
ID_Quit = 1,
ID_About,
};
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(ID_Quit, MyFrame::OnQuit)
EVT_MENU(ID_About, MyFrame::OnAbout)
END_EVENT_TABLE()
MyFrame::MyFrame(const wxString& title,
const wxPoint& pos, const wxSize& size)
: wxFrame((wxFrame *)NULL, -1, title, pos, size)
{
wxMenu *menuFile = new wxMenu;
menuFile->Append( ID_About, "&About..." );
menuFile->AppendSeparator();
menuFile->Append( ID_Quit, "E&xit" );
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append( menuFile, "&File" );
SetMenuBar( menuBar );
CreateStatusBar();
SetStatusText( "Welcome to wxWindows!" );
}
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
Close(TRUE);
}
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxMessageBox("This is a wxWindows Hello world sample",
"About Hello World", wxOK | wxICON_INFORMATION, this);
}
#endif

BEGIN_EVENT_TABLE() starts the event table definition, so it must be in a source file, not in a header (the event table declaration is, unsurprisingly, inside DECLARE_EVENT_TABLE()).

Related

Unresolved external symbol when assigning a function pointer to a function imported by DLL

I wasn't able to find a post with this particular issue. This is all in C, on a Windows target.
I have a DLL that I created, and some client code I created to test the DLL. The functions and types defined in the DLL are all successfully resolved by the client code except when I try to use a function pointer in the client code to a function defined in DLL.
Example:
/*--- DLL_Header.h ---*/
#ifdef BUILD_DLL
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
DLL_API void library_function(int foo, int bar);
/* --- DLL_source.c --- */
void library_function(int foo, int bar)
{
/* Do anything */
}
/* --- Client Code --- */
#include "DLL_Header.h"
void client_function_A()
{
int foo = 1;
int bar = 2;
library_function(foo,bar); /* This compiles and links with no problem! */
}
void client_function_B()
{
void (*lib_exec)(int foo, int bar);
lib_exec = &library_function; /* Compiles but then linker says unresolved external symbol __imp__library_function */
int x = 1;
int y = 2;
lib_exec(x,y);
}
client_function_B works fine if I just statically link everything, so it seems there is something I am not fundamentally understanding about the interaction between the DLL and function pointers. Can someone please help me understand what I am doing wrong, and why?
Edit: Exact error message
client_code.obj : error LNK2019: unresolved external symbol __imp__library_function referenced in function _client_function_B

How to call unadorned C++ function from C++/CLI

I've written a C++/CLI function which I can call from Fortran. It is specified as
extern "C"
{
void __declspec(dllexport) __cdecl someFunct(int val)
{
...
}
}
This works; it calls managed code, and I can call it from Intel Visual Fortran. When I dumpbin the DLL, I see that it is exported as _someFunct
I now want to call this function from another C++/CLI DLL. I've tried the following spec (with and without a leading underscore), but both fail the same way:
extern "C" extern __declspec(dllimport) void __cdecl someFunct(int val);
The error message I get is this:
Error 4 error LNK2028: unresolved token (0A00000A) "extern "C" void __cdecl someFunct(int)" (?someFunct##$$J0YAXH#Z) referenced in function "public: void __clrcall NUnitTesting::Class1::Test(void)" (?Test#Class1#NUnitTesting##$$FQ$AAMXXZ)
It seems the linker expects an adorned name, even though I specify extern "C" in the spec. How can I force the name to be unadorned?
Figured it out. My spec has to be preceeded by name of DLL:
using namespace System::Runtime::InteropServices;
[DllImport("DLL_with_someFunct",CallingConvention=CallingConvention::Cdecl)]
extern "C" extern void __cdecl someFunct(int val);

Managed DLL with C linkage used in CLR library

I have a project that was originally written in C. It's pretty large so I don't want to re-write it by hand if I can avoid it. The end goal is to embed it in a C# application. I've made and used CLR libraries before, but I'm having trouble with the below.
// CommandParse.h, used in a Win32 DLL
extern "C" {
typedef struct _PARAMS {
PCHAR OutputDir;
//... other members
} PARAMS, *PPARAMS;
// defines in CommandParse.c
__declspec(dllexport) VOID CmdParseParameters(PPARAMS, int, char ** const);
}
I'm using VS2013 for these projects. And the above example is the stereotypical design pattern used in every other component.
// CommandParseWrapper.h, CLR library
namespace WrappedCode {
public ref class CommandParams {
PPARAMS params;
public:
CommandParams() {
params = new PARAMS;
}
void parse(int argc, char ** const argv) {
CmdParseParameters(params, argc, argv);
}
}
}
What I've done in the CLR project is added the Win32DLL project as a reference and added the source code to the "Additional Includes" setting in VS2013. However I've presented with the following errors.
error LNK2019: unresolved external symbol "extern "C" void __cdecl CmdParseParameters(struct _PARAMS *, int, char** const)"...
error LNK2028: unresolved token (0A00002E) "extern "C" void __cdecl CmdParseParameters(struct _PARAMS *, int, char** const)"...
Causing the compilation to fail.
Any suggestions?
Note: I'm not against editing the original code.

warning C4013: 'logError' undefined; assuming extern returning int

I have a simple log macro, this is the .h file :
#ifndef __LOGGER_H
#define __LOGGER_H
#define LOG_ERROR(errorMsg) logError(__FILE__, __LINE__, errorMsg)
#endif
...and this is the .c file :
#include <stdio.h>
#include "Logger.h"
void logError(const char* filename, int line, const char* errorMsg)
{
printf("[File : %s] - [Line: %d} - [Error Message : %s]\n", filename, line, errorMsg);
}
When I use the macro in a .c file :
#include <Common/Logger.h>
void func(int index, int value)
{
if (IsIndexOutOfRange(index, NUMBER_OF_PARAMS))
{
LOG_ERROR("Index out of range!");
return;
}
.
.
.
}
...and build (vs2013) I get :
warning C4013: 'logError' undefined; assuming extern returning int
Warning C4013 usually means that you forgot to include the correct library or need to use extern. I suspect I need extern somehow, but do not know how to fix this with a macro.
How do I solve this?

allocate global pool in kernel mode

Hope i get an answer even if this question might sound silly.
I've read about allocating Memory with ExAllocatePoolWithTag now but i still do not know where i can iplement it and where i am not allowed to do it.
In my case i have to allocate a global buffer. This is the way i tried:
POOL.H
#ifndef _POOL_H_
#define _POOL_H_
typedef struct _POOL_LIST {
CHAR list_data[500] ;
struct _POOL_LIST* next;
}
POOL_LIST, * PPOOL_LIST;
#ifdef __cplusplus
extern "C" {
#endif
extern ULONG pcount;
extern PPOOL_LIST PoolData;
void poolinitialize();
void poolterminate();
#ifdef __cplusplus
};
#endif
#endif // _POOL_H_
POOL.C
#include "precomp.h"
#pragma hdrstop
ULONG pcount = 0;
void poolinitialize()
{
PoolData = (PPOOL_LIST*) ExAllocatePoolWithTag(NonPagedPool, GLOBALBUFFERMAX, 'tag1');
}
void poolterminate()
{
ExFreePoolWithTag(PoolData, 'tag1');
}
here i get a Linker Error in the WinXP x86 Checked Build Environment:
error LNK2001: unresolved external symbol _PoolData
error LNK1120: 1 unresolved externals
If i do not declare it extern, just PPOOL_LIST PoolData; i get another error
error LNK2005: _PoolData already defined in filter.obj
But i can declare pcount, why not PoolData ?
The extern keyword is used to say that the variable is located somewhere else - e.g. it exists somewhere. So complation works.
The linker is actually looking for an instance of PoolData and it failed to find it.
In your C file declare:
PPOOL_LIST PoolData; //without extern.
or
static PPOOL_LIST PoolData; // only accessible from this C file

Resources