I have a function bar() that I don't actually call, that calls unimplemented foo():
void foo();
void bar()
{
foo();
}
int main()
{
}
If I package each function in a separate section/COMDAT and ask the linker to remove unused sections/COMDAT, I can get gcc to compile the program
gcc -ffunction-sections -Xlinker --gc-sections LinkerFunctions.cpp
but the equivalent in Visual C++ 2019
cl /Gy LinkerFunctions.cpp /link /OPT:REF
barks that
error LNK2019: unresolved external symbol "void __cdecl foo(void)" (?foo##YAXXZ) referenced in function "void __cdecl bar(void)" (?bar##YAXXZ)
How can I get msvc to compile the program?
Got your example working by adding inline, even after adding __declspec(noinline) to prevent actual inlining.
void foo();
__declspec(noinline)
inline void bar()
{
foo();
}
int main()
{
}
Tried because the documentation says:
Inlined functions and member functions defined inside a class declaration are always COMDATs.
Not sure however if it is robust solution, or works just in this particular case.
Accidentally found a linker switch for that:
cl incomplete.cpp /link /FORCE:UNRESOLVED
Will give a warning but in fact will work.
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 having a problem with _beginthread in microsoft visual studio c++ 10 express:
my code:
void __cdecl DashThread( void * Args ) // function without any class refs
{
while(1){
MessageBox::Show("work");
Sleep(5000);
}
_endthread();
}
private:
System::Void button8_Click_1(System::Object^ sender, System::EventArgs^ e) {
HANDLE HDash = ( HANDLE ) _beginthread(DashThread, 0, NULL );
}
and errors:
error C3641: 'DashThread' : invalid calling convention '__cdecl ' for function compiled with /clr:pure or /clr:safe
error C2664: 'beginthread' : cannot convert parameter 1 from 'void (_cdecl *)(void *)' to 'void (__cdecl *)(void *)'
From the compiler error it seems you are compiling your project with /clr:pure or /clr:safe (in which case you are not programming in C++, but C++/CLI by the way) and thus cannot use the __cdecl calling convention, which is in turn required by _beginthread.
If you are programming in C++/CLI (and thus .NET) anyway, then why not just use .NET's threading facilities instead of the strange pseudo-standard-Win32-wrapper _beginthread?
If you want to use C++/CLI, but still be able to use good old _beginthread, then try to compile it with just /clr instead of /clr:pure, which allows non-managed functions that can have __cdecl calling convention.
Try to buid your program with /clr instead of /clr:pure.
See http://msdn.microsoft.com/en-us/library/k8d11d4s.aspx
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.
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've code like
A.h
Class A{
public:
void FuncA();
}
A.cpp
#include "A.h"
void A::FuncA() {}
B.h
#include "A.h"
Class B{
public:
void FuncB();
}
B.cpp
#include "B.h"
void B::FuncB(){
A *a = new A();
a->FuncA();
}
When I'm trying to build this project I'm geting "error LNK2019: unresolved external symbol "public: void __thiscall A::FuncA()" (?FuncA#A##QAEXH#Z) referenced in function "public: void __thiscall B::FuncB(void)" (?FuncB#B##MAEXXZ) B.obj project"
It makes A.obj and B.obj.
The code looks ok. Make sure to rebuild everything first and that A.obj is really sent to the linker.
Response to comment
Check the build log in VS2008. See picture below: