Strange issue...
This is using VisualStudio Community 2017 and is a C++CLI WinForms project.
BGStatsInterface.cpp
#include "BGStatsInterface.h"
using namespace System;
using namespace System::Windows::Forms;
[STAThreadAttribute]
void Main(array<String^>^ args) {
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
BattlegroundStats::BGStatsInterface form;
Application::Run(%form);
}
BGStatsInterface.h
#pragma once
#include <windows.h>
#include "LuaReader.h"
namespace BattlegroundStats {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::IO;
public ref class BGStatsInterface : public System::Windows::Forms::Form
{
public:
BGStatsInterface(void)
{
InitializeComponent();
this->MinimizeBox = false;
this->MaximizeBox = false;
}
static System::Windows::Forms::TextBox^ textBoxLog;
static System::Void addMsg(String^ text) {
textBoxLog->AppendText(text + "\n");
}
protected:
~BGStatsInterface()
{
if (components)
{
delete components;
}
}
private: LuaReader ^ reader = gcnew LuaReader();
private: System::Windows::Forms::Button^ b1;
private:
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
void InitializeComponent(void)
{
this->textBoxLog = (gcnew System::Windows::Forms::TextBox());
this->b1 = (gcnew System::Windows::Forms::Button());
this->SuspendLayout();
//
// textBoxLog
//
this->textBoxLog->BackColor = System::Drawing::SystemColors::ControlLightLight;
this->textBoxLog->Cursor = System::Windows::Forms::Cursors::IBeam;
this->textBoxLog->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 6.75F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point,
static_cast<System::Byte>(0)));
this->textBoxLog->Location = System::Drawing::Point(10, 80);
this->textBoxLog->Multiline = true;
this->textBoxLog->Name = L"textBoxLog";
this->textBoxLog->ReadOnly = true;
this->textBoxLog->ScrollBars = System::Windows::Forms::ScrollBars::Vertical;
this->textBoxLog->Size = System::Drawing::Size(280, 90);
this->textBoxLog->TabIndex = 6;
this->textBoxLog->TabStop = false;
this->textBoxLog->GotFocus += gcnew System::EventHandler(this, &BGStatsInterface::textBoxLog_HideCaret);
//
// b1
//
this->b1->Location = System::Drawing::Point(100, 30);
this->b1->Name = L"b1";
this->b1->Size = System::Drawing::Size(75, 23);
this->b1->TabIndex = 7;
this->b1->Text = L"DoSomething";
this->b1->UseVisualStyleBackColor = true;
this->b1->Click += gcnew System::EventHandler(this, &BGStatsInterface::b1_Click);
//
// BGStatsInterface
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(301, 411);
this->Controls->Add(this->b1);
this->Controls->Add(this->textBoxLog);
this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedSingle;
this->MaximumSize = System::Drawing::Size(317, 450);
this->MinimumSize = System::Drawing::Size(317, 450);
this->Name = L"BGStatsInterface";
this->Text = L"Test";
this->ResumeLayout(false);
this->PerformLayout();
}
#pragma endregion
System::Void textBoxLog_HideCaret(System::Object^ sender, System::EventArgs^ e) {
TextBox^ focus = safe_cast<TextBox^>(sender);
HideCaret((HWND)focus->Handle.ToPointer());
}
System::Void b1_Click(System::Object^ sender, System::EventArgs^ e) {
reader->DoSomething();
addMsg("DoingSomethingA");
System::Diagnostics::Debug::WriteLine("DoingSomethingA");
}
};
}
LuaReader.cpp
#include "LuaReader.h"
#include "BGStatsInterface.h" // PointA- This is where I'm having the issue.
using namespace System;
LuaReader::LuaReader(){}
System::Void LuaReader::DoSomething() {
BattlegroundStats::BGStatsInterface::addMsg("DoingSomethingB");
System::Diagnostics::Debug::WriteLine("DoingSomethingB");
}
LuaReader.h
#pragma once
#include "GameCollection.h" // PointB - Another issue here.
ref class LuaReader
{
public:
LuaReader();
GameCollection^ gameData = gcnew GameCollection();
System::String^ _fileName;
System::Void DoSomething();
};
#endif
GameCollection.cpp
#include "GameCollection.h"
GameCollection::GameCollection(){}
GameCollection.h
#pragma once
using namespace System;
ref class GameCollection
{
public:
GameCollection();
};
The Problem:
In LuaReader.cpp If I include BGStatsInterface.h (needed so it can access the addMsg method), noted by PointA, it wont compile and will generate the errors listed below.
However, if I remove the GameCollection.h include from LuaReader.h (needed so I can create the GameCollection object), noted at PointB, it has no issues with BGStatsInterface.h included in the LuaReader.cpp file and everything compiles/runs without issues.
I don't know what to do... Why does it only work if I don't create the GameCollection object in LuaReader.h?
What have I done wrong?
Errors:
Severity Code Description Project File Line Suppression State
Error (active) E1986 an ordinary pointer to a C++/CLI ref class or interface class is not allowed BattlegroundStats c:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\um\servprov.h 91
Error (active) E0266 "IServiceProvider" is ambiguous BattlegroundStats c:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\um\servprov.h 115
Error (active) E0266 "IServiceProvider" is ambiguous BattlegroundStats c:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\um\servprov.h 239
Error (active) E0266 "IServiceProvider" is ambiguous BattlegroundStats c:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\um\servprov.h 249
Error (active) E0266 "IServiceProvider" is ambiguous BattlegroundStats c:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\um\urlmon.h 6867
Error (active) E0266 "IServiceProvider" is ambiguous BattlegroundStats c:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\um\urlmon.h 6869
Error C3699 '*': cannot use this indirection on type 'IServiceProvider' BattlegroundStats c:\program files (x86)\windows kits\10\include\10.0.16299.0\um\servprov.h 91
Error C2371 'IServiceProvider': redefinition; different basic types BattlegroundStats c:\program files (x86)\windows kits\10\include\10.0.16299.0\um\servprov.h 98
Error C2872 'IServiceProvider': ambiguous symbol BattlegroundStats c:\program files (x86)\windows kits\10\include\10.0.16299.0\um\servprov.h 115
Error C2872 'IServiceProvider': ambiguous symbol BattlegroundStats c:\program files (x86)\windows kits\10\include\10.0.16299.0\um\servprov.h 239
Error C2872 'IServiceProvider': ambiguous symbol BattlegroundStats c:\program files (x86)\windows kits\10\include\10.0.16299.0\um\servprov.h 249
Error C2872 'IServiceProvider': ambiguous symbol BattlegroundStats c:\program files (x86)\windows kits\10\include\10.0.16299.0\um\urlmon.h 6867
Error C2872 'IServiceProvider': ambiguous symbol BattlegroundStats c:\program files (x86)\windows kits\10\include\10.0.16299.0\um\urlmon.h 6869
This happens when using #include Windows.h as it defines ::IServiceProvider while the framework has System::IServiceProvider, then when there's a using namespace System in scope somewhere it becomes ambiguous.
Solution is to simply put the delcarations in your own namespace.
Just providing another solution in here if your project is small - remove:
using namespace System;
and use full type name in the code for System's class, e.g. System::String^.
To fix this, put your include file (that has windows.h in it) before declaring your namespaces and/or using statements:
So:
#include "stdafx.h"
using namespace System;
instead of
using namespace System;
#include "stdafx.h"
Hat tip to http://www.windows-tech.info/17/fbe07cd4dfcac878.php
Related
I am trying to integrate libgit2 (1.5.0) into my project. The compilation failes due to missing type definitions.
The CMakeLists.txt of my project includes the include directory and the libgit2.a file:
target_include_directories(myprj PUBLIC ../libgit2/src/libgit2-1.5.0/include)
set(myprj "${CMAKE_SOURCE_DIR}/lib/libgit2.a")
link_directories(myprj ${PROJECT_SOURCE_DIR}/lib)
target_link_libraries(myprj PUBLIC ${libgit} crypto ssl)
The following code is a simplified version of the code I am using, but it should demonstrate the problem:
#include <git2.h>
git_reference *ref;
git_branch_t btype;
int code = git_branch_next(&ref, &btype, iterator);
if(code != 0)
return code;
char* name = ref->name;
The compiler fails with the error:
error: invalid use of incomplete typedef ‘git_reference’
char* name = ref->name
^~
The include directory defines the type but the stuct itself is defined in the src directory only.
libgit2-1.5.0/include/git2/types.h (source)
typedef struct git_reference git_reference;
libgit2-1.5.0/src/libgit2/refs.h(source)
struct git_reference {
//...
};
I have tried to fix it by importing the src dir into my project but this doesnt work because of missing includes.
Import in Cmake:
target_include_directories(myprj PUBLIC ../libgit2/src/libgit2-1.5.0/src/libgit2)
Error:
libgit2/src/libgit2-1.5.0/src/libgit2/common.h:10:10: fatal error: git2_util.h: File or directory not found
10 | #include "git2_util.h"
I think this is on purpose, to make git_reference an opaque type. It can then be changed at will by the library authors without breaking compatibility.
To get the name of a reference, use git_reference_name instead of accessing the field directly:
const char* name = git_reference_name(ref);
I've got a problem mixing the C++ and C code. My C++ code was created in VS10, i.e is a Windows Form project. I want include my C function in my C++ function through of linker (.obj). The steps are:
Windows Form project
VS10 default project
Call the C function
Build the project manually using msbuild
C code
Build the project manually through a make file using nmake and generates the objects files (.obj)
With the every objects files in hands (Cpp and C), the objects are linked in a third makefile. It's a simple idea but it doesn't work. The build in msbuild show the following message:
error LNK2028: unresolved token (0A00000C) "extern "C" void __clrcall MinhaFuncao(void)" (?MinhaFuncao##$$J0YMXXZ) referenced in function "int __clrcall main(cli::array^)" (?main##$$HYMHP$01AP$AAVString#System###Z)
error LNK2019: unresolved external symbol "extern "C" void __clrcall MinhaFuncao(void)" (?MinhaFuncao##$$J0YMXXZ) referenced in function "int __clrcall main(cli::array^)" (?main##$$HYMHP$01AP$AAVString#System###Z)
The Cpp code:
#include "stdafx.h"
#include "Form1.h"
//#include"complex.h"
extern "C" {
#include "complex.h"
}
/*extern "C" {
void MinhaFuncao();
}*/
extern "C" void MinhaFuncao();
using namespace WFormTesting;
[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
// Enabling Windows XP visual effects before any controls are created
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
MinhaFuncao(); //<--- Calling the Function HERE -->
// Create the main window and run it
Application::Run(gcnew Form1());
return 0;
}
The C code:
#include "complex.h"
void MinhaFuncao()
{
printf("My function AOWWW.\n");
}
The header file:
#ifndef COMPLEX_H_
#define COMPLEX_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdio.h>
void MinhaFuncao();
#ifdef __cplusplus
} // extern "C"
#endif
#endif
Has someone got an idea about this problem? I read others posts about linker issues, but the solutions proposed don't work for me. I believe that the difference is due to the msbuild and the VS project... :/
You are using extern "C" in an extern C block
remove the outer extern C block surrounding
#include "complex.h"
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.
Can anyone give a brief example of how to develop windows forms application with c++ and writing code in a cpp file
The question is,
do i have to write the whole code for runtime in the myform.h only,
can't i write any piece of code in the cpp or a c file?
as in a C++ standard program, you can write your code in a cpp file, for exemple :
For the button event, let the prototy in the header file :
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e);
And then, in a C++ source file, you can do :
#include "stdafx.h"
#include "Form1.h"
using namespace System;
using namespace System::Windows::Forms;
using namespace <your_project_namespace>;
Void Form1::button1_Click(Object^ sender, EventArgs^ e)
{
double result = 0.0;
double input;
if (Double::TryParse(this->textBox1->Text, input))
{
result = input * 2.5;
this->label1->Text = "Result= " + result + ".";
}
}
Don' forgot to include your Form header file and use the good namespace. See the result :
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()).