SHGetKnownFolderPath: ambiguous symbol 'IServiceProvider'? - c++-cli

I'm trying to create a folder for my app in /AppData/local so that i can save some ini files in it, i tried to get the Destination path using:
#include <ShlObj.h>
if (SHGetKnownFolderPath (FOLDERID_LocalAppData, 0, NULL, &tempPath) == S_OK)
{
....
}
It doesn't work and gives me these errors:
Error 1 error C2872: 'IServiceProvider' : ambiguous symbol c:\program files\windows kits\8.0\include\um\ocidl.h 6482 1 Project2
Error 2 error C2872: 'IServiceProvider' : ambiguous symbol C:\Program Files\Windows Kits\8.0\Include\um\shobjidl.h 9181 1 Project2
I tried adding #pragma comment (lib, "Shell32.lib") and linking the Shell32.lib in the project settings and nothing changed.
The errors disappear when i remove #include <ShlObj.h> but then the SHGetKnownFolderPath function becomes undefined. How can i fix this?
Note: I'm on Windows 7
Edit: My Project Header files are:
MyForm.h
#pragma once
#define CRTDBG_MAP_ALLOC
#include "gamepad.h"
#include "configure.h"
#include <stdlib.h>
#include <crtdbg.h>
#include <Dbt.h>
namespace Project2 {
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::Diagnostics;
public ref class MyForm : public System::Windows::Forms::Form
{
public:
MyForm(void)
{
InitializeComponent();
this->gamepad = gcnew Gamepad();
this->SETTINGS = gcnew Settings();
}
....
};
}
gamepad.h
#pragma once
#include <Windows.h>
#include <WinUser.h>
#include <tchar.h>
#define _USE_MATH_DEFINES
#include <math.h>
extern "C"
{
#include <hidsdi.h>
}
#include "InputHandler.h"
#include "keycodes.h"
using namespace System;
public ref class Gamepad
{
....
}
configure.h
#pragma once
#include "keycodes.h"
#include <Windows.h>
#include <Shlwapi.h>
#include <ShlObj.h>
#include <msclr\marshal.h>
using namespace System;
using namespace System::Diagnostics;
using namespace System::IO;
using namespace msclr::interop;
public ref class Settings
{
public:
Settings(void)
{
PWSTR tempPath;
if (SUCCEEDED (SHGetKnownFolderPath (FOLDERID_LocalAppData, 0, NULL, &tempPath)))
Debug::WriteLine (gcnew String (tempPath));
else Debug::WriteLine ("Failed");
}
}

IServerProvider is indeed ambiguous, it exists both as an COM interface type in the servprov.h Windows SDK header file and as .NET interface type in the System namespace.
Simplest way to repro your problem is to put the using namespace directive in the wrong spot:
#include "stdafx.h"
using namespace System;
#include <ShlObj.h>
Bam, 18 errors. No problemo if you order them right:
#include "stdafx.h"
#include <ShlObj.h>
using namespace System;
Careful with those using directives, they are really good at creating ambiguity.

IServerProvider is ambiguous because it is a COM interface type in servprov.h (which you get with windows.h) and as a .NET interface type in the System namespace.
If you don't need all the APIs in windows.h, you can #define WIN32_LEAN_AND_MEAN to get a subset that excludes the IServiceProvider definition and avoids the ambiguity.
Do the #define before the #include and it's probably a good idea to #undef afterward, like this:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN

Related

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.

Visual Studio 2012 Update 3 Managed Test for C++/CLI

I am having issues using visual studio 2012 managed test project with a c++/cli dll.
The first problem is the warnging MSB3274 could not be resolved because it was built against the ".NETFramework,Version=v4.5" framework. This is a higher version than the currently targeted framework "
I cant find any property page in the managed test project to change the targeted framework and if i unload the project and edit the project i cant find the tag to change this.
the next problem is a linker error
error LNK2020: unresolved token (06000001).
followed by another linker error
error LNK1120: 1 unresolved externals
C++/CLI project
Header file:
#pragma once
using namespace System;
namespace MathLibrary {
public ref class CustomMathLibrary
{
public:
int Sum(int number1, int number2);
};
}
CPP File:
#include "MathLibrary.h"
int MathLibrary::CustomMathLibrary::Sum(int number1, int number2)
{
return number1 + number2;
}
I then link this project to the managed test project by adding the reference in the properties dialog -> common properties -> Framework and Reference
I then add the header file in the properties dialog -> configuration properties -> C/C++ -> additional include directories
the unit test cpp file
#include "stdafx.h"
#include "MathLibrary.h"
using namespace System;
using namespace System::Text;
using namespace System::Collections::Generic;
using namespace Microsoft::VisualStudio::TestTools::UnitTesting;
namespace ImdMathLibraryTest
{
[TestClass]
public ref class MathLibTest
{
public:
[TestMethod]
void SumTest()
{
Assert::AreEqual(1,1);
}
};
}
thank you to all for any advice to resolve this issue.

include different headers for cases

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.