I have created an MFC DLL and have exported the functions for example in the file SerialPort.h:
class CSerialPortApp : public CWinApp
{
public:
CSerialPortApp();
__declspec(dllexport) int SWrite(unsigned char* toSend, int len);
};
and in my MFC application I want to call the function in SerialInterface.h I have included the "SerialPort.h" from the DLL and called:
__declspec(dllimport) int SWrite(unsigned char* toSend, int len);
class SerialInterface
{
public:
};
for example.
I have added the SerialPort.lib file to my linker includes but when I try to compile I get
error LNK2001: unresolved external symbol "__declspec(dllimport) int __cdecl SWrite(unsigned char*, int)" (__imp_?SWrite##YAHPAEH#Z)
I am stuck as to the cause of this, I have tried rebuilding everything but nothing seems to help?
Thank you for any help!
You are using __declspec(dllexport) inside a class?
You either export global functions from the dll or whole class which may contain any functions. You don't have to export selected member functions from a class, I don't even know how that works.
It is a little strange that you are not properly exporting the SerialPort class from dll (as per your code) yet you can use it in your application and call its member function!? I am a little confused.
Well I found an alternative that works, I believe I was implementing it incorrectly.
I added a new class to my DLL that was not a CWinApp class:
class SerialPort
{
public:
__declspec(dllexport) SerialPort(void);
__declspec(dllexport) virtual ~SerialPort(void);
__declspec(dllexport) int SWrite(unsigned char* toSend, int len);
};
then included the header for this in my application and the lib and dll etc.
I then placed the included header file in the main CDialog header but importantly didn't need to import any of the functions:
#include "SerialPort.h"
class CPPUDlg : public CDialog
{
public:
CPPUDlg(CWnd* pParent = NULL); // standard constructor
SerialPort objSerialPort;
and then in my code I simply call
objSerialPort.SWrite(toSend, len);
I have not used dllimport to import the functions which I assumed I would need to but it now works!
Hope this helps anyone who may have a similar problem.
Related
I am trying to use Microsoft CppUnitTestFramework. I have two separate projects in one solution, one the actual code and the other one is the unit test code. Now I would like to test the "DijkstarImpl" class defined in the first project and I added the path for this class in project Properties->C++->General->AdditionalInclude directories. The test project compiles successfully, but when I run the test I get this error:
Error 2 error LNK2001: unresolved external symbol "public: static class DijkstarImpl * UnitTest_FasTrack::UnitTest1::dijkstarImpl" (?dijkstarImpl#UnitTest1#UnitTest_FasTrack##2PAVDijkstarImpl##A) C:\working\TestFastTrack\UnitTest_FasTrack\unittest1.obj
Error 3 error LNK2001: unresolved external symbol "public: __thiscall DijkstarImpl::DijkstarImpl(void)" (??0DijkstarImpl##QAE#XZ) C:\working\TestFastTrack\UnitTest_FasTrack\unittest1.obj
The error is the linker error, but I don't know what should I link? It is not a lib file to be included in Properties->Linker->Input.
The following snippet shows the unit test code.
#include "stdafx.h"
#include "CppUnitTest.h"
#include "DijkstarImpl.h"
#include "string.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace UnitTest_FasTrack
{
TEST_CLASS(UnitTest1)
{
static DijkstarImpl* dijkstarImpl;
public:
TEST_CLASS_INITIALIZE(Initialize)
{
static DijkstarImpl* UnitTest_FasTrack::UnitTest1::dijkstarImpl;
}
TEST_METHOD(TestMethod1)
{
}
};
}
You need to declare an instance of the variable outside the class, but in the same namespace.
namespace UnitTest_FasTrack
{
TEST_CLASS(UnitTest1)
{
static DijkstarImpl* dijkstarImpl;
public:
TEST_CLASS_INITIALIZE(Initialize)
{
}
TEST_METHOD(TestMethod1)
{
}
};
DijkstarImpl *UnitTest1::dijkstarImpl; //declared outside the scope of the class
}
I'm getting this error:
error C3767: 'phys1::point::get_prev': candidate function(s) not accessible
Here's my code
phys.h
using namespace System;
namespace phys1 {
typedef struct position{
int x;
int y;
} pos;
public ref class point{
public:
point(float speed, float gr);
public:
pos get_prev();
public:
pos get_next();
};
}
phys.cpp
// This is the main DLL file.
#include "phys.h"
using namespace System;
namespace phys1 {
...
static pos point::get_prev(){
pos point;
point.x=x;
point.y=y;
return point;
}
...
}
Is it problem with my struct, which i try to use in library? Can i build it in another way?
You are mixing C++ syntax and C++/CLI syntax. The "struct" is a native definition (a C++ one).
To declare 'struct' you should better use the "value struct" construction.
The "not accessible" error can also be due to the 'position' being implicitly declared as 'private'.
See more about managed type declarations here: http://www.codeproject.com/Articles/17741/C-CLI-in-Action-Declaring-CLR-types
If you're trying to pass values of type pos across an assembly boundary, it should be a public managed type. public value struct pos would be most appropriate for what you're doing.
Native types aren't visible across assembly boundaries by default, and the #pragma that makes them visible is more of a kludge than a real solution. Just make a proper .NET type with metadata.
I have an Xcode project which includes OpenFeint as a dependency. OpenFeint has one class that makes two calls to Block_copy() and one call to Block_release(). All was well (as in, I built and ran the project a number of times without incident) until suddenly the compiler started complaining that these functions don't exist. The thing literally broke in between two builds, with no changes to the source code in between.
I have no idea where these functions could have gone, but I've attempted to work around it by providing some placeholder function prototypes, like so:
extern void* Block_copy(const void *aBlock);
extern void Block_release(const void *aBlock);
I'm not sure if those are the correct signatures (the documentation on this topic is sparse, at best), but it's the closest I've been able to find. Sadly, this just causes the linker to complain instead of the compiler.
So any ideas? Is my whole development environment screwed? If not, how do I get it working again?
Did you switch XCode or perhaps iOS (hinting at something recently released for developers). It might be that, if you switched to ARC accidentally, those functions may no longer exist (ARC isn't under NDA since it already existed and is open source).
The actual definition of Block_copy is in
/Developer/SDKs/MacOSX10.6.sdk/usr/include/Block.h
and reads
#define Block_copy(...) ((__typeof(__VA_ARGS__))_Block_copy((const void *)(__VA_ARGS__)))
and _Block_copy is defined in the same file by
BLOCK_EXPORT void *_Block_copy(const void *aBlock);
Providing your own definition will not help Xcode. Has your target in XCode changed ?
A temporary workaround is to inline the entire contents of 'Block.h' in the OpenFeint source file. Strangely, trying to #include or #import the file does not work, which may be the whole of the problem.
In any case, this file should exist at /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator[VERSION].sdk/usr/include/Block.h, and the contents should be:
#ifndef _Block_H_
#define _Block_H_
#if !defined(BLOCK_EXPORT)
# if defined(__cplusplus)
# define BLOCK_EXPORT extern "C"
# else
# define BLOCK_EXPORT extern
# endif
#endif
#include <Availability.h>
#include <TargetConditionals.h>
#if __cplusplus
extern "C" {
#endif
// Create a heap based copy of a Block or simply add a reference to an existing one.
// This must be paired with Block_release to recover memory, even when running
// under Objective-C Garbage Collection.
BLOCK_EXPORT void *_Block_copy(const void *aBlock)
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
// Lose the reference, and if heap based and last reference, recover the memory
BLOCK_EXPORT void _Block_release(const void *aBlock)
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
// Used by the compiler. Do not call this function yourself.
BLOCK_EXPORT void _Block_object_assign(void *, const void *, const int)
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
// Used by the compiler. Do not call this function yourself.
BLOCK_EXPORT void _Block_object_dispose(const void *, const int)
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
// Used by the compiler. Do not use these variables yourself.
BLOCK_EXPORT void * _NSConcreteGlobalBlock[32]
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
BLOCK_EXPORT void * _NSConcreteStackBlock[32]
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
#if __cplusplus
}
#endif
// Type correct macros
#define Block_copy(...) ((__typeof(__VA_ARGS__))_Block_copy((const void *)(__VA_ARGS__)))
#define Block_release(...) _Block_release((const void *)(__VA_ARGS__))
#endif
I am trying to create a Managed C++/CLI object in unmanaged code.
Is this possible?
If so, am I doing it right? see code below
#include <vcclr.h>
#include <ManagedClass.h>
// compiled with /clr
namespace X
{
class UnmanagedClass
{
UnmanagedClass(){}
~UnmanagedClass(){}
gcroot<Y::ManagedClass^> m_guiControl;
void functionA()
{
m_guiControl = new gcroot<Y::ManagedClass^>;
}
}
}
// compiled into Managed dll with /clr
// in file ManagedClass.h in a separate project
using namespace System::ComponentModel;
// more usings here ..etc
namespace Y {
public ref class ManagedClass : public System::Windows::Forms::UserControl
{
// implementation here
}
}
When I compile the UnmanagedClass source file, I keep getting a whole lot of errors with the first one being error C2039: 'ComponentModel' : is not a member of 'System'. How come it is not recognising ComponentModel?
I thought this was suppose to be IJW (it just works) ;-)
Here's an example for a wrapper:
class UnmanagedClass
{
gcroot<ManagedClass^> m_managed;
public:
UnmanagedClass()
{
m_managed = gcnew ManagedClass();
}
};
Look here:
C++/CLI - Managed class to C# events
wrapper to c++/cli
Edit:
When you get an error on a using statement, and you know it's supposed to exist, It's usually because that dll isn't referenced.
Go to the projects references, choose add reference.
You can add .Net assemblies in the .Net tab. Find the one you need and add it.
I am writing a c++ static library A.lib in visual studio 2008. In my static library, I am using few APIs exposed by another static library B.lib(.lib).
I have a written an application that uses A.lib. Since few header files in A.lib are using headers from B.lib, my application wants a path of B.lib header files. How can I avoid my application so that I need not to provide path of B.lib header files for compilation ?
Refrain from using types from B-headers in the interface of your library. A good way of totally hiding the implementation is using the factory-pattern along with pure abstract base classes as interfaces. You will still have to link B.lib in your application though.
Sample Before:
// A.h
#include "B.h"
class Foo {
public:
void DoStuff();
private:
B::Bar Data; // B::Data comes from library B
};
This in your header adds a dependency to B.
With Factory, your application now uses IFoo.h instead of A.h:
// IFoo.h
class IFoo {
public:
static IFoo * CreateInstance( ); // implemented in IFoo.cpp, just returns new Foo
virtual void DoStuff() = 0;
virtual ~IFoo() {}
};
// A.h
class Foo : public IFoo {
public:
virtual void DoStuff();
private:
B::Bar Data; // B::Data comes from library B
};
You can go to settings and add the directory to the additional include directory's and you can just use the header by name.