I'm migrating the code of an dll, developed with C++, from Visual Studio version 2008 to 2010.
I'm facing this error below which is related to the 'C:\Program Files\Microsoft Visual Studio 10.0\VC\include\xstring'.
Error C2678: binary operator '!=': no operator found which takes a left-hand operand of type 'c_allocator<_Ty>' (or there is no acceptable conversion).
The error occurs with the line 'class c_allocator: public std::_Allocator_base<_Ty>{'.
#include <stdlib.h>
#include <vector>
#include "Synchro.h"
template<class _Ty>
class c_allocator: public std::_Allocator_base<_Ty>{
public:
typedef _Allocator_base<_Ty> _Mybase;
typedef typename _Mybase::value_type value_type;
typedef value_type _FARQ *pointer;
typedef value_type _FARQ& reference;
typedef const value_type _FARQ *const_pointer;
typedef const value_type _FARQ& const_reference;
typedef _SIZT size_type;
typedef _PDFT difference_type;
template<class _Other>struct rebind{
typedef c_allocator<_Other> other;
};
pointer address(reference _Val) const {
return (&_Val);
}
const_pointer address(const_reference _Val) const {
return (&_Val);
}
c_allocator() _THROW0() {
}
c_allocator(const c_allocator<_Ty>&) _THROW0() {
}
template<class _Other>c_allocator(const c_allocator<_Other>&) _THROW0() {
}
template<class _Other>c_allocator<_Ty>& operator=(const c_allocator<_Other>&) {
return (*this);
}
void deallocate(pointer _Ptr, size_type) {
CustomAlloc::LinearAllocHolder<1>::alloc.freemem(_Ptr);
}
pointer allocate(size_type _Count) {
return (pointer)CustomAlloc::LinearAllocHolder<1>::alloc.getmem(_Count*sizeof(value_type));
}
pointer allocate(size_type _Count, const void _FARQ *) {
return (allocate(_Count));
}
void construct(pointer _Ptr, const _Ty& _Val) {
std::_Construct(_Ptr, _Val);
}
void destroy(pointer _Ptr) {
std::_Destroy(_Ptr);
}
_SIZT max_size() const _THROW0() {
_SIZT _Count = (_SIZT)(-1) / sizeof (_Ty);
return (0 < _Count ? _Count : 1);
}
};
Any hint much appreciated -
thanks in advance -
surplus
Related
I want to export a class type that derives from a __interface(only available for Visual c++),which aiming to create c#-like inteface-oriented experience.
//This wiil be defined in a "Famous.h"
__interface IFoo {
int GetNum();
};
//And this is my implementation.
#include "...Famous.h"
class FooImpl : public IFoo
{
public:
FooImpl(int a);
private:
int a;
};
FooImpl::FooImpl(int a)
{
this->a = a;
}
The problem is ,How could I export the 'FoolImpl' type to use it as follows in another project without refrencing the project directly.I tried dllexport,and tons of errors make me exthausted :(.
#include "..Impl.h"
#include "..Famous.h"
void main(){
IFoo* foo = new FooImpl(2);
...
}
Considering of there's no interface in c++,I replaced the __interface with pure virtual class.
//This wiil be defined in a "Famous.h"
#ifdef FAMOUS_EXPORTS
#define XYZAPI __declspec(dllexport)
#else
#define XYZAPI __declspec(dllimport)
#endif
class XYZAPI IFoo {
virual int GetNum() = 0;//void type also valid.
};
//And this is my implementation(Impl.h).
#ifdef IMPL_EXPORTS
#define XYZAPI __declspec(dllexport)
#else
#define XYZAPI __declspec(dllimport)
#endif
#include "...Famous.h"
class XYZAPI FooImpl : public IFoo
{
public:
FooImpl(int a);
private:
int a;
};
FooImpl::FooImpl(int a)
{
this->a = a;
}
And this is my invocation.
#include "..Impl.h"
#include "..Famous.h"
void main(){
IFoo* foo = new FooImpl(2);
...
}
I'm trying to use Boost library in my C++ Windows Form Application and I always get an exception:
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
I'm using Visual Studio 2012 and Boost version 1.57.0. Previously I used Boost version 1.56.0 but upgrading didn't solve my issue.
Here are the code:
MyForm.cpp
#include "MyForm.h"
using namespace System;
using namespace System::Windows::Forms;
[STAThread]
void main(cli::array<String^>^ args) {
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
TestUnmanaged::MyForm form;
Application::Run(%form);
}
MyForm.h
#pragma once
#include <iostream>
#include <map>
#include <sstream>
#include <cassert>
#include <stdio.h>
#include "ExternalProfileManager.h"
#define DEFAULT_PROFILE_NAME "profile.bin"
#pragma comment(lib, "Ws2_32.lib")
#pragma comment(lib, "lib/edk.lib")
namespace TestUnmanaged {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
ExternalProfileManager profileManager;
/// <summary>
/// Summary for MyForm
/// </summary>
public ref class MyForm : public System::Windows::Forms::Form
{
public:
MyForm(void)
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
profileManager.load(DEFAULT_PROFILE_NAME);
std::vector<std::string> profileList;
profileManager.listProfile(profileList);
}
ExternalProfileManager.h
#ifndef EXTERNAL_PROFILE_MANAGER_H
#define EXTERNAL_PROFILE_MANAGER_H
#include <boost/serialization/string.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/tracking.hpp>
#include <boost/serialization/base_object.hpp>
class ExternalProfileManager
{
ExternalProfileManager(const ExternalProfileManager&) {};
ExternalProfileManager& operator = (const ExternalProfileManager&) {};
protected:
std::map<std::string, std::string > _profiles;
typedef std::map<std::string, std::string >::iterator profileItr_t;
// Boost serialization support
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive& ar, const unsigned int /*file version */)
{
ar & _profiles;
}
public:
ExternalProfileManager();
virtual ~ExternalProfileManager();
virtual bool save(const std::string& location);
virtual bool load(const std::string& location);
virtual bool insertProfile(const std::string& name, const unsigned char* profileBuf, unsigned int bufSize);
virtual bool listProfile(std::vector<std::string>& profiles);
};
//BOOST_CLASS_EXPORT(ExternalProfileManager);
//BOOST_CLASS_TRACKING(ExternalProfileManager, boost::serialization::track_never);
#endif // EXTERNAL_PROFILE_MANAGER_H
ExternalProfileManager.cpp
#include <fstream>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/regex.hpp>
#pragma warning(push)
#pragma warning(disable : 4267) // "conversion from size_t to unsigned int"
#pragma warning(disable : 4996)
#include <boost/archive/archive_exception.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#pragma warning(pop)
#include "ExternalProfileManager.h"
using namespace std;
namespace fs = boost::filesystem;
ExternalProfileManager::ExternalProfileManager()
{
}
ExternalProfileManager::~ExternalProfileManager()
{
}
bool ExternalProfileManager::save(const string& location)
{
ofstream ofs(location.c_str(), ios_base::binary);
if ( !ofs.is_open() ) return false;
try {
boost::archive::binary_oarchive oa(ofs);
oa << *this;
}
catch (boost::archive::archive_exception& )
{
return false;
}
return true;
}
bool ExternalProfileManager::load(const string& location)
{
ifstream ifs(location.c_str(), ios_base::binary);
if ( !ifs.is_open() ) return false;
try {
boost::archive::binary_iarchive ia(ifs);
ia >> *this;
}
catch (boost::archive::archive_exception& )
{
return false;
}
return true;
}
bool ExternalProfileManager::insertProfile(const string& name, const unsigned char* profileBuf, unsigned int bufSize)
{
assert(profileBuf);
// Replace our stored bytes with the contents of the buffer passed by the caller
string bytesIn(profileBuf, profileBuf+bufSize);
_profiles[name] = bytesIn;
return true;
}
bool ExternalProfileManager::listProfile(vector<string>& profiles)
{
profiles.clear();
for ( profileItr_t itr = _profiles.begin(); itr != _profiles.end(); ++itr ) {
profiles.push_back(itr->first);
}
return true;
}
The error occurred in ia >> *this; in ExternalProfileManager::load (thrown in file basic_archive.cpp). So calling profileManager.load(DEFAULT_PROFILE_NAME); from form constructor will trigger the exception.
Calling save will also trigger the same exception but other functions which have no this will work fine.
I tried creating a console application in VS 2012 and call ExternalProfileManager.h and it works perfectly (including save, load, and any other function). Here are the simple console application I created to test it:
Console.cpp
#include <iostream>
#include <map>
#include <sstream>
#include <cassert>
#include <stdio.h>
#include "ExternalProfileManager.h"
#define DEFAULT_PROFILE_NAME "profile.bin"
#pragma comment(lib, "Ws2_32.lib")
#pragma comment(lib, "lib/edk.lib")
ExternalProfileManager profileManager;
int main(int argc, char** argv) {
profileManager.load(DEFAULT_PROFILE_NAME);
std::vector<std::string> profileList;
profileManager.listProfile(profileList);
std::cout << "Available profiles:" << std::endl;
for (size_t i=0; i < profileList.size(); i++) {
std::cout << i+1 << ". " << profileList.at(i);
if (i+1 < profileList.size()) {
std::cout << std::endl;
}
}
return true;
}
profile.bin is generated from calling save function in console application and contain serialized data generated by boost. I can provide the file if it is needed to solve this issue.
I have also tried to create a simple class wrapper but the exception still occurred.
WrapperExternalProfileManager.h
#ifndef WRAPPER_EXTERNAL_PROFILE_MANAGER_H
#define WRAPPER_EXTERNAL_PROFILE_MANAGER_H
#include <string>
#include <vector>
class WrapperExternalProfileManager
{
WrapperExternalProfileManager(const WrapperExternalProfileManager&) {};
WrapperExternalProfileManager& operator = (const WrapperExternalProfileManager&) {};
public:
WrapperExternalProfileManager();
virtual ~WrapperExternalProfileManager();
virtual bool save(const std::string& location);
virtual bool load(const std::string& location);
virtual bool insertProfile(const std::string& name, const unsigned char* profileBuf, unsigned int bufSize);
virtual bool listProfile(std::vector<std::string>& profiles);
};
#endif
WrapperExternalProfileManager.cpp
#include "WrapperExternalProfileManager.h"
#include "ExternalProfileManager.h"
using namespace std;
ExternalProfileManager profileManager;
WrapperExternalProfileManager::WrapperExternalProfileManager()
{
std::cout<<"Constructor WrapperExternalProfileManager"<<std::endl;
}
WrapperExternalProfileManager::~WrapperExternalProfileManager()
{
}
bool WrapperExternalProfileManager::save(const string& location)
{
return profileManager.save(location);
}
bool WrapperExternalProfileManager::load(const string& location)
{
return profileManager.load(location);
}
bool WrapperExternalProfileManager::insertProfile(const string& name, const unsigned char* profileBuf, unsigned int bufSize)
{
return profileManager.insertProfile(name, profileBuf, bufSize);
}
bool WrapperExternalProfileManager::listProfile(vector<string>& profiles)
{
return profileManager.listProfile(profiles);
}
save and load still trigger the exception but other functions work perfectly.
Here are some property of the application which might be helpful:
Linker -> System -> SubSystem: Windows (/SUBSYSTEM:WINDOWS)
General -> Common Language Runtime Support: Common Language Runtime Support (/clr)
I know I have done something incorrectly but I don't know which part. Any suggestion to solve this issue would be appreciated.
Thanks in advance
You're going to have to find the source of your Undefined Behaviour (use static analysis tools, heap checking and divide and conquer).
I've just built your code on VS2013 RTM, using a ultra-simple C# console application as the driver:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var f = new TestUnmanaged.MyForm();
f.ShowDialog();
}
}
}
This JustWorks(TM).
I created a profile.bin with 100 random profiles of varying length:
#if 1
for (int i = 0; i < 100; ++i)
{
std::vector<uint8_t> buf;
std::generate_n(back_inserter(buf), rand() % 1024, rand);
insertProfile("profile" + std::to_string(i), buf.data(), buf.size());
}
save(location);
#endif
And they are deserialized just fine.
Good luck.
Download the full project here http://downloads.sehe.nl/stackoverflow/q27032092.zip in case you want to fiddle with it (compare the details?)
I'm trying to pass an object by reference in c++. I get these errors:
Error 1 error C2061: syntax error : identifier 'Common' graphics.h 6 1 SDLGameDev
Error 2 error C2511: 'void Graphics::CreateWindow(Common &)' : overloaded member function not found in 'Graphics' 4 1 SDLGameDev
I found answers about this area, but not any that covers how to do this:
object1.someFunction(object2);
Here is my code:
//Common.h
#ifndef COMMON_H
#define COMMON_H
#include "SDL.h"
#include "iostream"
class Common{
public:
void Init();
bool GetGameRunState(){ return GameRunState; }
void SetGameRunState(bool x){ GameRunState = x; }
private:
bool GameRunState;
};
#endif
//Commmon.cpp
#include "Common.h"
void Common::Init()
{
if (SDL_Init(SDL_INIT_EVERYTHING) == 0)
{
SetGameRunState(true);
}
else
{
SetGameRunState(false);
}
}
//Graphics.h
#ifndef GRAPHICS_H
#define GRAPHICS_H
class Graphics{
public:
void CreateWindow(Common & co);
};
#endif
//Graphics.cpp
#include "Graphics.h"
#include "Common.h"
void Graphics::CreateWindow(Common & co)
{
if (co.GetGameRunState() == true)
{
std::cout << "TEST for CreateWindow()\n";
}
}
//main.cpp
#include "Common.h"
#include "Graphics.h"
Common co;
Graphics go;
int main(int argc, char * args[])
{
co.Init();
go.CreateWindow(co);
while (co.GetGameRunState() == true)
{
std::cout << "Game is running\n";
SDL_Delay(2000);
break;
}
return 0;
}
You haven't included Common.h in the file Graphics.h so it doesn't know about the class.
#ifndef GRAPHICS_H
#define GRAPHICS_H
#include "Common.h" // You need this line
class Graphics {
public:
void CreateWindow(Common & co);
};
#endif
I would recommend using singletons and put the initialisation of sdl, creation of the renderer and window etc all together in one class. Your question has already been answered.
I'm trying to extend Python with C++. I'm using Visual C++ 2008 and Python 2.7. I have had a lot of problems building the .dll file, and finally when it seemed to be everything correct, I can't stop getting this error:
error LNK2001: unresolved external symbol _imp_Py_InitModule4
I know it isn't a linker error because I had this error before (it gave me the error but with all kind of Py_... functions) and I had resolved that.
I don't know if this is an important data but I have build python27_d.dll with VC++ 2008 too.
This is the code:
#include "Python.h"
#include <windows.h>
#include <string.h>
#include <tchar.h>
#include <stdlib.h>
#include <Aclapi.h>
struct file_perms {
char user_domain[2050];
unsigned long user_mask;
};
void lookup_sid ( ACCESS_ALLOWED_ACE* pACE, char user_domain[] ) {
char username[1024]="";
char domain[1024]="";
ULONG len_username = sizeof(username);
ULONG len_domain = sizeof(domain);
PSID pSID =(PSID)(&(pACE->SidStart));
SID_NAME_USE sid_name_use;
LPWSTR username1 = reinterpret_cast<LPWSTR>( username );
LPWSTR domain1 = reinterpret_cast<LPWSTR>( domain );
if (!LookupAccountSid(NULL, pSID, username1, &len_username, domain1, &len_domain, &sid_name_use)){
strcpy(user_domain, "unknown");
} else {
strcat(user_domain,domain);
strcat(user_domain,"\\");
strcat(user_domain,username);
}
}
void acl_info( PACL pACL, ULONG AceCount, file_perms fp[]){
for (ULONG acl_index = 0;acl_index < AceCount;acl_index++){
ACCESS_ALLOWED_ACE* pACE;
if (GetAce(pACL, acl_index, (PVOID*)&pACE))
{
char user_domain[2050]="";
lookup_sid(pACE,user_domain);
strcpy(fp[acl_index].user_domain,user_domain);
fp[acl_index].user_mask=(ULONG)pACE->Mask;
}
}
}
static PyObject *get_perms(PyObject *self, PyObject *args)
{
PyObject *py_perms = PyDict_New();
//get file or directory name
char *file;
if (!PyArg_ParseTuple(args, "s", &file))
return NULL;
//setup security code
PSECURITY_DESCRIPTOR pSD;
PACL pDACL;
//GetNamedSecurityInfo() will give you the DACL when you ask for
//DACL_SECURITY_INFORMATION. At this point, you have SIDs in the ACEs contained in the DACL.
LPWSTR file1 = reinterpret_cast<LPWSTR>( file );
ULONG result = GetNamedSecurityInfo(file1,SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL,
&pDACL, NULL, &pSD);
if (result != ERROR_SUCCESS){ return NULL;}
if (result == ERROR_SUCCESS){
ACL_SIZE_INFORMATION aclSize = {0};
if(pDACL != NULL){
if(!GetAclInformation(pDACL, &aclSize, sizeof(aclSize),
AclSizeInformation)){
return NULL;
}
}
file_perms *fp = new file_perms[aclSize.AceCount];
acl_info(pDACL, aclSize.AceCount, fp );
//Dict
for (ULONG i=0;i<sizeof(fp);i++){
PyObject *domain = Py_BuildValue("s",fp[i].user_domain);
PyObject *user = Py_BuildValue("s",fp[i].user_mask);
PyDict_SetItem(py_perms,domain,user);
}
}
return py_perms;
};
static PyMethodDef fileperm_methods[] = {
{ "get_perms", get_perms, METH_VARARGS, "Execute a shell command." },
{ NULL, NULL, 0, NULL }
};
extern "C"
__declspec(dllexport)
void init_fileperm(void)
{
PyObject *m=Py_InitModule("fileperm",fileperm_methods);
return;
}
I'm working in Windows 7 64bits.
I know that Py_InitModule is deprecated for Python 3 but I'm working in Python27 (2.7.3 ).
Does someone know why I get this error?
Thanks!
I had the same problem.
If you're compiling a 64-bit pyd, make sure python27.lib is also 64-bit (same goes for compiling a 32-bit pyd with a 32-bit python27.lib).
Does anyone know why this code is not compilable with VC++ 2010
class C
{
public:
void M(string t) {}
void M(function<string()> func) {}
};
void TestMethod(function<void()> func) {}
void TestMethod2()
{
TestMethod([] () {
C c;
c.M([] () -> string { // compiler error C2668 ('function' : ambiguous call to overloaded function)
return ("txt");
});
});
}
Update:
Full code example:
#include <functional>
#include <memory>
using namespace std;
class C
{
public:
void M(string t) {}
void M(function<string()> func) {}
};
void TestMethod(function<void()> func) {}
int _tmain(int argc, _TCHAR* argv[])
{
TestMethod([] () {
C c;
c.M([] () -> string { // compiler erorr C2668 ('function' : ambiguous call to overloaded function M)
return ("txt");
});
});
return 0;
}
This is a bug of the VC++ Compiler.
https://connect.microsoft.com/VisualStudio/feedback/details/687935/ambiguous-call-to-overloaded-function-in-c-when-using-lambdas
You did not post the error message, so by looking into my crystal ball I can only conclude that you suffer those problems:
Missing #includes
You need at the top
#include <string>
#include <functional>
Missing name qualifications
You either need to add
using namespace std;
or
using std::string; using std::function;
or
std::function ...
std::string ...
Missing function main()
int main() {}
Works with g++
foo#bar: $ cat nested-lambda.cc
#include <string>
#include <functional>
class C
{
public:
void M(std::string t) {}
void M(std::function<std::string()> func) {}
};
void TestMethod(std::function<void()> func) {}
void TestMethod2()
{
TestMethod([] () {
C c;
c.M([] () -> std::string { // compiler error C2668
return ("txt");
});
});
}
int main() {
}
foo#bar: $ g++ -std=c++0x nested-lambda.cc
Works fine.