include different headers for cases - c++-cli

Is it possible to use for case 1 one header and for case 2 another?
Because when I use both headers in program I've got ambiguous symbol errors.
header 1(winapifunctions.h)
#include <Windows.h>
void CallWindowProc(String^ windowtitle)
{
};
header 2(classes.h)
using namespace System;
using namespace System::Collections::Generic;
public delegate void Super();
public ref class Event{};
public ref class MyException:public DivideByZeroException{};
public interface class IType{};
public interface class IVal{};
public ref class Writer abstract{};
public ref class Check: public Writer,public IType,public IVal
.....other classes
main program
#include "stdafx.h"
#include "classes.h"
#include "winapifunctions.h"
int main(array<System::String^>^ args)
{
//read x
switch(x){ case 1: {CallWindowProc("title");break;} case 2: { Check^ obj = gcnew Check();break;}
};
and error - IServiceProvider:ambiguous symbol

Short answer: No.
Long answer: includes are processed by the pre-processor, during compile time, while your case statements are processed during runtime. There's no way to make a compile-time thing to happen during runtime.
What are you trying to achieve exactly?

You can work around this problem using the following code:
// 1.cpp
case 1:
DoCase1();
break;
case 2:
DoCase2();
break;
// 2.cpp
#include <Windows.h>
void DoCase1()
{
// ...
}
// 3.cpp
#include <AnotherHeader.h>
void DoCase2()
{
// ...
}
If you would post more code and exact error messages, perhaps a better solution can be found.

Related

Trying to use C# DLL with ComVisible attribute set from unmanaged C++

TL;DR: I'm trying to use a C# library in C++. Why am I getting an undeclared identifier error when trying to use an identifier from my .tlh file? There must be tons of examples out there, but I haven't been able to find any that include both the C# and C++ code, and that work. Links to such examples would be greatly appreciated.
I have the following classes defined in C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using CrystalDecisions.CrystalReports.Engine;
namespace CapsCrystalReportLib
{
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[Guid("B4E5F784-12E6-4311-9BB9-D5B3252F20A3")]
public interface ICapsCrystalReport
{
[DispId(1)]
void DisplayReport(string fileName);
[DispId(2)]
void PrintReport(string fileName);
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[Guid("89402DE5-BA26-4AC0-AB40-00ADD2876FF4")]
[ProgId("CAPSCrystalReport.Report")]
[ComDefaultInterface(typeof(ICapsCrystalReport))]
public class CapsCrystalReport : ICapsCrystalReport
{
public void DisplayReport(string fileName)
{
MessageBox.Show("Displaying report " + fileName);
}
public void PrintReport(string fileName)
{
MessageBox.Show("Printing report " + fileName);
}
}
}
I have the following C++ program attempting to use this class:
#include "stdafx.h"
#import "W:\\CAPS Builds\\trunk\\CapsCrystalReportLib\\bin\\Debug\\CapsCrystalReportLib.tlb" no_namespace
int _tmain(int argc, _TCHAR* argv[])
{
// Initialize COM.
HRESULT hr = CoInitialize(NULL);
// Create the interface pointer.
CapsCrystalReport CRPtr(__uuidof(CapsCrystalReport));
long lResult = 0;
// Call the Add method.
CRPtr->DisplayReport("SomeReport.rpt");
// Uninitialize COM.
CoUninitialize();
return 0;
}
I am getting an undeclared identifier error. The compiler doesn't know what a CapsCrystalReport is. What am I doing wrong?
P.S. I took another look at the sample I copied this from. One of the comments asks the same question, and it was never answered.
You were very close, but CRPtr is a COM interface reference (=pointer) so it must be declared like this:
ICapsCrystalReportPtr CRPtr(__uuidof(CapsCrystalReport));
The IxxxPtr class was generated for you by #import in a .tlh file. What you can do when you have issues with #import, is just open the generated .tlh file and look at it.
Note you don't have to declare a default interface in C#, you can just declare the class like this:
[ComVisible(true)]
[Guid("89402DE5-BA26-4AC0-AB40-00ADD2876FF4")]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ProgId("CAPSCrystalReport.Report")]
public class CapsCrystalReport
{
... same ...
}
And in C++, you would have to adapt your imports like this:
#import "C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319\mscorlib.tlb" auto_rename
#import "W:\\CAPS Builds\\trunk\\CapsCrystalReportLib\\bin\\Debug\\CapsCrystalReportLib.tlb" no_namespace
and you would use it like that (the interface was implicitely created by .NET and wrapped by the #import):
_CapsCrystalReportPtr CRPtr(__uuidof(CapsCrystalReport));
PS: I would recommend you to keep the namespace, avoid no_namespace because it can cause problems with collisions especially in C++.

Static Object of a class in another class in aggregation relationship C++

I have two classes first class contains the object of another class as static but C++ doesnot allow me to do this and gives me some error.
source.cpp
#include"control.h"
int main()
{
Controller cnt;
cnt.tempcont();
return 0;
}
control.h
#include"recorder.h"
class Controller
{
public:
static recorder rec;
void tempcont();
};
recorder Controller::rec;
control.cpp
#include"control.h"
void Controller::tempcont()
{
rec.temprec();
}
recorder.h
#include<iostream>
using namespace std;
class recorder
{
public:
int a;
void temprec();
};
recorder.cpp
#include"recorder.h"
void recorder::temprec()
{
cout << "temp rec called";
}
I am getting the following errors and i have no idea why these errors are comming..
Error LNK1169 one or more multiply defined symbols found
Error LNK2005 "public: static class recorder Controller::rec" (?rec#Controller##2Vrecorder##A) already defined in control.obj
You define the variable Controller::rec in the header file. That means the variable will be defined in every translation unit where that header file have been included. It should only be defined in one single translation unit.
This is very easy to do: Just move the definition to a single source file.

ERROR, vertex_descriptor': is not a member of 'StitchPolyhedron', if StitchPolyhedron is inherited from Polyhedron_3

There is an error if class inherits from Polyhedron_3 and used in stitch_borders, but if I use the Polyhedron_3 directly in stitch_borders there is no error.
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
class StitchPolyhedron : public CGAL::Polyhedron_3<K>
{
public:
StitchPolyhedron() {}
virtual ~StitchPolyhedron() {}
};
StitchPolyhedron mesh;
CGAL::Polygon_mesh_processing::stitch_borders(mesh);
Code above gives an error
vertex_descriptor': is not a member of 'StitchPolyhedron'
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Polyhedron_3<K> StitchPolyhedron;
StitchPolyhedron mesh;
CGAL::Polygon_mesh_processing::stitch_borders(mesh);
Code above compiles fine.
Can anyone point me what is the issue here.
Your inherited class must be a model of FaceListGraph. Usually adding in a boost namespace the following partial specialization should be sufficient:
namespace boost {
struct boost::graph_traits<POLYHEDRON_TYPE>:
public boost::graph_traits<BASE_POLYHEDRON_TYPE>
{};
} // namespace boost
You might need to forward properties as well. Add in a boost namespace the following partial specialization:
namespace boost{
template <class Tag>
struct property_map<POLYHEDRON_TYPE, Tag> :
public property_map<BASE_POLYHEDRON_TYPE, Tag>
{};
} //namespace boost

EntryPointNotFoundException occurred while calling C++ function from C#

I wish to call C++ function (here Score()) which is present in Score_Update1.dll.
Both C# & C++ files get compiled successfully. I have also put above dll into the Debug/bin of C# project. But when I run C# code it gives EntryPointNotFoundException.
What could be the reason behind this Exception?
I tried dependency walker for Score_Update1.dll. But it doesn't show any Entry Point
I wish to use PInvoke technique for calling C++ function from C#
// Score_Update1.h
#pragma once
#include <iostream>
using namespace std;
using namespace System;
extern "C"{
#define MYAPI __declspec(dllexport)
namespace Score_Update1 {
public class MYAPI UpdateScore
{
// TODO: Add your methods for this class here.
public:
void Score();
};
}
}
// This is the main Score_Updat1.dll DLL file.
#include "stdafx.h"
#include "Score_Update1.h"
using namespace Score_Update1;
void UpdateScore::Score()
{
cout<<"Score has been updated";
}
C# code is as follows:
using Score_Update1;
using System.Runtime.InteropServices;
namespace GameTesting
{
class Game
{
[DllImport("Score_Update1.dll")]
internal extern static void Score();
static void Main(string[] args)
{
try
{
Game.Score();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
}
The reason for EntryPointNotFoundException is that the DLL does not contain an entry point named Score. If you look at the exported names using dumpbin or some similar tool you will see mangled names.
However, using the mangled name isn't going to help you here. You've exported a class and the function you want to call is a member function. You cannot directly instantiate a C++ class from pinvoke. And you cannot call member functions. If you wish to use pinvoke you would need to flatten the class to a C style interface. Another route would be to compile the C++ code to a mixed mode C++/CLI assembly and consume that.

Use library in windows form application

I need to use WinSparkle library in my Windows Form Application. I have include library header - <winsparkle.h> and have placed DLL import code. I suppose Dll import code is C# style. How to convert it to C++ .Net style?
// AutoUpdate.cpp : main project file.
#include "stdafx.h"
#include "Form1.h"
#include <winsparkle.h>
using System;
using System::Runtime::InteropServices;
using namespace AutoUpdate;
namespace AutoUpdate // YOUR NAMESPACE CAN GO HERE
{
**// C# lines**
class WinSparkle
{
// Note that some of these functions are not implemented by WinSparkle YET.
[DllImport("WinSparkle.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern void win_sparkle_init();
[DllImport("WinSparkle.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern void win_sparkle_cleanup();
[DllImport("WinSparkle.dll", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)]
public static extern void win_sparkle_set_appcast_url(String url);
[DllImport("WinSparkle.dll", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.Cdecl)]
public static extern void win_sparkle_set_app_details(String company_name,
String app_name,
String app_version);
[DllImport("WinSparkle.dll", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)]
public static extern void win_sparkle_set_registry_path(String path);
[DllImport("WinSparkle.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern void win_sparkle_check_update_with_ui();
}
}
[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
// Enabling Windows XP visual effects before any controls are created
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
// Create the main window and run it
Application::Run(gcnew Form1());
return 0;
}
You seem to be getting a little confused here.
You certainly could do this with a mixed mode C++/CLI assembly. You'd include the header file and pass the lib file to the linker. Then you could call the functions directly since they are declared in the header file. You'd need to call the functions from the C++/CLI assembly, or expose whatever is needed through a managed ref class for consumption by the C# code.
However, the document you link to does not suggest this route. It suggests no C++/CLI at all and a pure C# p/invoke solution. That would appear to be the simplest approach.
I recommend that you remove the C++/CLI layer and instead use pure C# p/invoke. Follow precisely the instructions to which you linked. Start from the section titled Managed code / .NET / C# applications.