C++/CLI Windows Forms - creating custom DLL library - winforms

Today I wanted to make my own dynamic library. I am using VC++ 2010. Tried to apply a console example (from http://msdn.microsoft.com/en-us/library/ms235636%28v=vs.80%29.aspx) but I keep failing. Here are steps I follow:
Create Win32 project and choose Empty Project, DLL from wizard,
Create a header with
// FILE: bday.h
#ifndef BDAY_H_
#define BDAY_H_
#ifdef BUILD_DLL
#define PORT_DLL __declspec(dllexport)
#else
#define PORT_DLL __declspec(dllimport)
#endif
namespace Tests
{
public class BDay
{
public:
static PORT_DLL double Foo(double);
};
};
#endif
Create a .cpp to implement that class,
Build this project which is successful.
Then I go with
Create Windows Forms project, add reference to the previously created .dll,
Include bday.h from the previous project.
Define BUILD_DLL constant,
Add a button which calls Tests::BDay::Foo upon clicking.
Building this project gives me
1>CoreResGen:
1> Processing resource file "Form1.resX" into "Debug\generatory2.Form1.resources".
1>generatory2.obj : error LNK2028: unresolved token (0A00000F) "public: static double __cdecl Tests::BDay::Foo(double)" (?Foo#BDay#Tests##$$FSANN#Z) referenced in function "private: void __clrcall generatory2::Form1::button4_Click(class System::Object ^,class System::EventArgs ^)" (?button4_Click#Form1#generatory2##$$FA$AAMXP$AAVObject#System##P$AAVEventArgs#4##Z)
1>generatory2.obj : error LNK2019: unresolved external symbol "public: static double __cdecl Tests::BDay::Foo(double)" (?Foo#BDay#Tests##$$FSANN#Z) referenced in function "private: void __clrcall generatory2::Form1::button4_Click(class System::Object ^,class System::EventArgs ^)" (?button4_Click#Form1#generatory2##$$FA$AAMXP$AAVObject#System##P$AAVEventArgs#4##Z)
1>C:\Users\Patryk\Documents\Visual Studio 2010\Projects\generatory2\Debug\generatory2.exe : fatal error LNK1120: 2 unresolved externals
There must me something that I'm doing wrong, can you point out where the error is?

If you want to reference it as .Net class and method, you need to make it so.
The dll export/import is for unmanaged code. (Native c++ in your case).
In a c++ project you'd have to compile the .dll with a matching .lib file, and then link the lib file so the function can be found.
In a .Net library on the other hand, you just need to reference the dll. But for that it need to be compiled as a .Net library.
Compile the dll with the /CLR flag. And make the class a reference .Net class:
namespace Tests
{
public ref class BDay
{
public:
static double Foo(double);
};
};
You don't need the declspec export and import for .Net

Related

Access Golang code from a C project in Visual Studio 2019

I have a C project in Visual Studio 2019 and I would like to use certain functions written in Go within it.
I have a test file called ctest.go which has the following contents:
package main
import (
"C"
"fmt"
)
//export printInt
func printInt(x int) {
fmt.Printf("Hello from go: %d", x)
}
func main() {}
I'm generating a static library with this command:
go build -buildmode=c-archive ctest.go
I end up with two files, ctest.a and ctest.h which I include in my VS project. I include ctest.h in my code and immediately get these errors:
identifier "__SIZE_TYPE__" is undefined
expected a ';'
expected a ';'
The generated header file contains the following lines which caused it:
typedef __SIZE_TYPE__ GoUintptr;
typedef float _Complex GoComplex64;
typedef double _Complex GoComplex128;
I replaced __SIZE_TYPE__ by size_t and just commented out the _Complex lines to stop the errors.
Now my VS project compiles while including the header file. But as soon as I try to use my go function like this:
printInt(5);
I get 2 warnings followed by 6 errors:
Warning LNK4078 multiple '.text' sections found with different attributes (60600060) AWO F:\AWO\AWO\ctest.a(go.o)
Warning LNK4078 multiple '.text' sections found with different attributes (60600060) AWO F:\AWO\AWO\ctest.a(go.o)
Error LNK2019 unresolved external symbol __imp___iob referenced in function __cgo_preinit_init AWO F:\AWO\AWO\ctest.a(000005.o)
Error LNK2001 unresolved external symbol __imp___iob AWO F:\AWO\AWO\ctest.a(000006.o)
Error LNK2001 unresolved external symbol __imp___iob AWO F:\AWO\AWO\ctest.a(000007.o)
Error LNK2019 unresolved external symbol _fprintf referenced in function _x_cgo_sys_thread_create AWO F:\AWO\AWO\ctest.a(000005.o)
Error LNK2001 unresolved external symbol _fprintf AWO F:\AWO\AWO\ctest.a(000007.o)
Error LNK1120 2 unresolved externals AWO F:\AWO\Debug\AWO.exe 1
This is where I'm stuck. I'm not sure what I'm doing wrong or should be doing differently to properly use the library generated with go.
project properties -> linker -> input -> additional dependencies
legacy_stdio_definitions.lib;%(AdditionalDependencies)
add source code
C
FILE* __cdecl __iob_func(void)
{
FILE _iob[] = { *stdin, *stdout, *stderr };
return _iob;
}
C++
extern "C" { FILE __iob_func[3] = { *stdin,*stdout,*stderr }; }

Debugging a DLL for C w/Visual Studio 2015

I'm writing a DLL for an existing application. The DLL is designed to interface to commercial software who's functionality can be enhanced by adding a user defined feature with a DLL.
My DLL compiles and the application can utilize the features, but I want to debug it. It is difficult for me to attach to the process and debug when the commercial software is calling the DLL. Instead, I'd like to build separate code to test the DLL.
All the examples I can find w/DLL's are for C# or C++. I can't quite understand how to do this in C. I seem to be stuck at importing the DLL or referencing the library in the linker.
I've inserted:
__declspec(dllimport) int UserDefinedSurface4(USER_DATA *UD, FIXED_DATA4 *FD);
but I get:
LNK2019 unresolved external symbol "__declspec(dllimport) int __cdecl UserDefinedSurface4(struct USER_DATA *,struct FIXED_DATA4 *)" (__imp_?UserDefinedSurface4##YAHPEAUUSER_DATA##PEAUFIXED_DATA4###Z)
Following advice for C# and C++, I've added a path to the DLL in my project using: Properties->Linker->Input->Additional Dependencies with an explicit path: "D:......\mydll.lib" (that seems kind of brittle... is this right or should I use a relative path or ...?)
Furthermore, I also inserted:
#pragma comment(lib, "D:\\...\\mydll.lib")
and I have included the project with the DLL in my references. What's missing?
Your dll import looks fine.
Check the name of the exported function. Good tool for this task is "Dependency Walker". If your dll compiled as C++, function name can be mangled. To prevent name mangling your export definition in DLL project should be:
extern "C" __declspec(dllexport) int UserDefinedSurface4(USER_DATA *UD, FIXED_DATA4 *FD);
In your application specify Linker -> Additional Library Directories to your library directory and in Linker -> Input specify additional dependency mydll.lib. After that check Linker -> Command Line parameter, it should contains:
"mydll.lib" /LIBPATH:"d:\yourlibrarydir\"

LNK2019 unresolved external symbol _GetExtendedTcpTable#24 [duplicate]

During coding in Visual Studio I got an unresolved external symbol error
and I've got no idea what to do. I don't know what's wrong.
Could you please decipher me? Where should I be looking for what kind of errors?
1>Form.obj : error LNK2019: unresolved external symbol "public: class Field * __thiscall Field::addField(class Field *)" (?addField#Field##QAEPAV1#PAV1##Z) referenced in function "public: void __thiscall Form::parse(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" (?parse#Form##QAEXAAV?$basic_stringstream#DU?$char_traits#D#std##V?$allocator#D#2##std###Z)
1>Form.obj : error LNK2019: unresolved external symbol "public: virtual void __thiscall Field::parse(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" (?parse#Field##UAEXAAV?$basic_stringstream#DU?$char_traits#D#std##V?$allocator#D#2##std###Z) referenced in function "public: __thiscall InputField::InputField(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" (??0InputField##QAE#AAV?$basic_stringstream#DU?$char_traits#D#std##V?$allocator#D#2##std###Z)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Field::prompt(void)" (?prompt#Field##UAEXXZ)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Field::getName(void)" (?getName#Field##UAE?AV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##XZ)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Field::getType(void)" (?getType#Field##UAE?AV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##XZ)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Field::describe(void)" (?describe#Field##UAEXXZ)
1>C:\Users\tomy\Documents\Visual Studio 2010\Projects\zapoctovkac++\Debug\zapoctovkac++.exe : fatal error LNK1120: 6 unresolved externals
This error often means that some function has a declaration, but not a definition.
Example:
// A.hpp
class A
{
public:
void myFunc(); // Function declaration
};
// A.cpp
// Function definition
void A::myFunc()
{
// do stuff
}
In your case, the definition cannot be found. The issue could be that you are including a header file, which brings in some function declarations, but you either:
do not define the functions in your cpp file (if you wrote this code yourself)
do not include the lib/dll file that contains the definitions
A common mistake is that you define a function as a standalone and forget the class selector, e.g. A::, in your .cpp file:
Wrong: void myFunc() { /* do stuff */ }
Right: void A::myFunc() { /* do stuff */ }
Check you are including all the source files within your solution that you are referencing.
If you are not including the source file (and thus the implementation) for the class Field in your project it won't be built and you will be unable to link during compilation.
Alternatively, perhaps you are using a static or dynamic library and have forgotten to tell the linker about the .libs?
It looks to be missing a library or include, you can try to figure out what class of your library that have getName, getType etc ... and put that in the header file or using #include.
Also if these happen to be from an external library, make sure you reference to them on your project file. For example, if this class belongs to an abc.lib then in your Visual Studio
Click on Project Properties.
Go to Configuration Properties, C/C++,
Generate, verify you point to the abc.lib location under Additional
Include Directories. Under Linker, Input, make sure you have the
abc.lib under Additional Dependencies.
I've just seen the problem I can't call a function from main in .cpp file, correctly declared in .h file and defined in .c file. Encountered a linker error. Meanwhile I can call function from usual .c file. Possibly it depends on call convention. Solution was to add following preproc lines in every .h file:
#ifdef __cplusplus
extern "C"
{
#endif
and these in the end
#ifdef __cplusplus
}
#endif
I had an error where my project was compiled as x64 project. and I've used a Library that was compiled as x86.
I've recompiled the library as x64 and it solved it.
sometimes if a new header file is added, and this error starts coming due to that, you need to add library as well to get rid of unresolved external symbol.
for example:
#include WtsApi32.h
will need:
#pragma comment(lib, "Wtsapi32.lib")
I had the same link errors, but from a test project which was referencing another dll. Found out that after adding _declspec(dllexport) in front of each function which was specified in the error message, the link was working well.
Yet another possible problem (that I just scratched my head about for some time):
If you define your functions as inline, they—of course!—have to be defined in the header (or an inline file), not a cpp.
In my case, they were in an inline file, but only because they were a platform specific implementation, and a cpp included this corresponding inl file… instead of a header. Yeah, s**t happens.
I thought I'd leave this here, too, maybe someone else runs into the same issue and finds it here.
This error can be caused by putting the function definitions for a template class in a separate .cpp file. For a template class, the member functions have to be declared in the header file. You can resolve the issue by defining the member functions inline or right after the class definition in the .h file.
For example, instead of putting the function definitions in a .cpp file like for other classes, you could define them inline like this:
template<typename T>
MyClassName {
void someFunction() {
// Do something
...
}
void anotherFunction() {
// Do something else
...
}
}
Or you could define them after the class definition but in the same file, like this:
template<typename T>
MyClassName {
void someFunction();
void anotherFunction();
}
void MyClassName::someFunction() {
// Do something
...
}
void MyClassName::anotherFunction() {
// Do something else
...
}
I just thought I'd share that since no one else seems to have mentioned template classes. This was the cause of the error in my case.
In addition to the excellent answer by Chris Morris above, I found a very interesting way you can receive this same fault if you are calling to a virtual method that hasn't been set to pure but doesn't its own implementation. It is the exact same reason (the compiler can't find an implementation of the method and therefore crooks), but my IDE did not catch this fault in the least bit.
for example, the following code would get a compilation error with the same error message:
//code testing an interface
class test
{
void myFunc();
}
//define an interface
class IamInterface
{
virtual void myFunc();
}
//implementation of the interface
class IamConcreteImpl
{
void myFunc()
{
1+1=2;
}
}
However, changing IamInterface myFunc() to be a pure virtual method (a method that "must" be implemented, that than a virtual method which is a method the "can" be overridden) will eliminate the compilation error.
//define an interface
class IamInterface
{
virtual void myFunc() = 0;
}
Hopes this helps the next StackOverFlow person stepping through code!
I believe most of the points regarding the causes and remedies have been covered by all contributors in this thread. I just want to point out for my 'unresolved external' problem, it was caused by a datatype defined as macro that gets substituted differently than expected, which results in that incorrect type being supplied to the function in question, and since the function with type is never defined, it couldn't have been resolved. In particular, under C/C++ -> Language, there is an attribute called 'Treat WChar_t As Built in Type, which should have been defined as 'No (/Zc:wchar_t-)' but did not in my case.
I just had a hard time with this. Everything was logically set up. I declared a constructor but didn't define it
class SomeClass
{
SomeClass(); // needs the SomeClass::SomeClass(){} function defined somewhere, even here
}
I almost banged my head on my keyboard when I forgot something so elementary.
See Linker Tools Error LNK2019 at MSDN, it has a detailed list of common problems that cause LNK2019.
Make sure you decorate your header files with
#ifndef YOUR_HEADER_H
#define YOUR_HEADER_H
// your header code here
#endif
Bad things -including this- can happen if you don't
I'm doing some C++ for the first time in a long time, and I'm getting this error when I forget to add the ClassName:: prefix for the function definition, since this is a little unique to C++. So remember to check for that too!
POINTERS
I had this problem and solved it by using pointer. I see that this wasn't your issue but I thought I'd mention it because I sure wish it had been here when I saw this an hour ago. My issue was about declaring a static member variable without defining it (the definition needed to come after some other set ups) and of course a pointer doesn't need a definition. Equally elementary mistake :P
One possible cause of this linker error can also be inline functions that are declared but not defined in a header file that is then included somewhere else. Inline functions have to be defined in every translation unit they are used in.
Make sure that you are not trying to overload the insertion or extraction operators as inline functions. I had this problem and it only went away when i removed that keyword.
What had caused it in my case:
I had a huge file Foo.cpp without a Foo.h. Foo.cpp began like this:
// ... 100 LOC here ...
namespace NS {
// ... 100 more LOC here ...
static int var;
I removed the "static" keyword and added a Foo.h with this:
extern int var;
Do you see the mistake?
I totally missed that var was originally defined in a namespace, because the namespace declaration was buried in other code. The fix is to change the extern like this:
namespace NS {
extern int var;
}
In my case, I needed add the function name to the DEF file.
LIBRARY DEMO
EXPORTS
ExistingFunction #1
MyNewFunction #2
My issue was a sconscript did not have the cpp file defined in it. This can be very confusing because Visual Studio has the cpp file in the project but something else entirely is building.
My issue was: I had to do forward declaration of the class whose ctor was "unresolved external".
In the file where I got the error, I had to put something like this:
#include "ClassB"
class ClassB; // this solved the problem
class ClassA{
void foo(){
ClassB* tmp = new ClassB();
// ...
}
};
Of course, my project is much more complicated and this is just a snippet example. Also when using namespaces, declare them as well.
Just spent a couple of hours to find that the issue was my main file had extension .c instead of .cpp
:/
Yet another possibility to check, it was my problem this time.
I had added the function to the library, and included the library's output folder in the search path.
But I also had a folder with an older version of the library listed before, so VS was using the old library, and of course not finding the new function.
A possible reason for the "Unresolved external symbol" error can be the function calling convention.
Make sure that all the source files are using same standard (.c or .cpp), or specify the calling convention.
Otherwise, if one file is a C file (source.c) and another file is a .cpp file, and they link to the same header, then the "unresolved external symbol" error will be thrown, because the function is first defined as a C cdecl function, but then C++ file using the same header will look for a C++ function.
To avoid the "Unresolved external symbol error", make sure that the function calling convention is kept the same among the files using it.
I came here looking for a possible explanation before taking a closer look at the lines preceding the linker error. It turned out to have been an additional executable for which the global declaration was missing!
I faced a similar issue and finally managed to solve it by adding __declspec(dllimport) to the declaration of the class:
// A.hpp
class __declspec(dllimport) A
{
public: void myFunc();
// Function declaration
};
In my case I had multiple namespaces in my header file without nesting (one after the other) however in my source file I had accidentally nested one of the namespaces inside another:
// myExample.h
#ifndef MYEXAMPLE_H
#define MYEXAMPLE_H
namespace A
{
void aFunc();
}
namespace B
{
void bFunc();
}
// myExample.cpp
#include "myExample.h"
namespace A
{
void aFunc()
{
...
}
namespace B // whoops! I nested this inside namespace A when I didn't mean to.
{
void bFunc()
{
...
}
}
}
// main.cpp
#include "myExample.h"
int main()
{
myExample::B::bFunc();
return 0;
}
When I used F12 to "Go to definition" on the function in Main, Visual Studio found the code in the source file even though it was declared in a deeper namespace by accident.
Debugging Technique
I spotted the issue when renaming the function while trying to debug the issue. The rename preview window showed an "External References" node with the function inside the source file clearly nested under another namespace by accident.
I had the same issue. Mine was working one day and then not the next day after I pulled the latest code.
The latest code did not include the project I was referencing in my library. So when I rebuilt my library, it deleted that .obj file, whoopsy.....
I reincluded the project I needed, built my library, then rebuilt my project that was failing and it worked fine.
Moral of the story, verify your .obj file is where you are referencing it before diving too deep into the rabit hole.
I have had an issue with the same error within my project which I have managed to resolved.
The problem led me here but I found it to be a build file problem within visual studio itself.
If you cannot find anything wrong with your code and your doing all of the above I would recommend looking in the yourProject.vcxproj file and check that it is including your MyClass.cpp and source files as
SynthProject.vcxproj
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="myClass.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="myClass.h" />
</ItemGroup>
SynthProject.vcxproj.filters
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="myClass.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="myClass.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
and not as
SynthProject.vcxproj
<ItemGroup>
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="myClass.h" />
<ClInclude Include="myClass.cpp" />
</ItemGroup>
SynthProject.vcxproj.filters
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="myClass.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="myClass.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="myClass.cpp">
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup>
I have managed to do this manually but would recommend unloading and adding the file back into the project if you do not have, or not using git.

LNK2019 (unresolved external symbol) when linking against built dynamic library in QT

I am using QT 5.5.0 within QtCreator to build a C++ application (referenced to as "the application" from now on) which I am trying to link against dynamic link C library ("the library"). All methods which originate from this library cannot be found by the linker when building the application, example output for one method:
error: LNK2019: unresolved external symbol "__declspec(dllimport) int __cdecl rlwe_FFT_CTX_init(struct fft_ctx *)" (__imp_?rlwe_FFT_CTX_init##YAHPAUfft_ctx###Z) referenced in function [...]
The library is imported by the following statement in the .pro file:
LIBS += "-L$$_PRO_FILE_PWD_/../../Libraries/rlwekex/Build/rlwekex/Release/Win32/" -lrlwekex
I expect this to work, since qmake is running fine and the linker will output another error if I change this to a non-existent library name. Both the application and the library are 32 bit.
The .lib and .dll files for the library have been built by myself using Visual Studio 2013. The same header files are used for building the library and as includes inside the application. A compile switch will mark methods as __declspec(dllexport) or __declspec(dllimport) using the following code:
# ifdef RLWEKEX_DLL_EXPORT
# define RLWEKEX_EXPORT __declspec(dllexport)
# else
# define RLWEKEX_EXPORT __declspec(dllimport)
# endif
The macros are correctly evaluated in both the library (export) as well as the application (import). The signature of the example method would be as follows:
RLWEKEX_EXPORT int rlwe_FFT_CTX_init(FFT_CTX *ctx);
Using dumpbin I can verify that the method is actually exported to the .lib - corresponding /HEADERS entry:
Version : 0
Machine : 14C (x86)
TimeDateStamp: 563B4D17 Thu Nov 05 13:35:35 2015
SizeOfData : 0000001F
DLL name : rlwekex.dll
Symbol name : _rlwe_FFT_CTX_init
Type : code
Name type : no prefix
Hint : 2
Name : rlwe_FFT_CTX_init
I have another Visual Studio 2013 project which is a test suite (written in C) for this particular library, which is linking against it just fine! QtCreator and Visual Studio 2013 are running on the same machine and are both using the same compiler toolkit (msvc).
Now of course my question: What could be the reason that I can link against the library in the VS2013 test suite, but not in the QT project? Any help would be appreciated!
C++ mangles names of functions while C does not.
The header file for the library needs to contain, near the beginning of the file, something like:
#ifdef __cplusplus
extern "C" {
#endif
and near the end of the header file
#ifdef __cplusplus
}
#endif
Note: the above lines are between the 'include guards', not to replace them
.

Prevent Visual Studio from exporting a function in a static library

Odd question: I'm building a static library with Visual Studio and I'm using a source file with a list of utility functions that I also use in the executable project that is importing the static library. As a result I'm getting errors like this:
4>newfuncs.lib(util.obj) : error LNK2005: _shift_left already defined in util.obj
4>newfuncs.lib(util.obj) : error LNK2005: _chop already defined in util.obj
4>newfuncs.lib(util.obj) : error LNK2005: _crc_begin already defined in util.obj
4>newfuncs.lib(util.obj) : error LNK2005: _crc_update already defined in util.obj
4>newfuncs.lib(util.obj) : error LNK2005: _crc_result already defined in util.obj
4>newfuncs.lib(util.obj) : error LNK2005: _strtok_r already defined in util.obj
Anyone know how I could figure out how to get Visual Studio to NOT export the functions in util.obj, since those are natively present in the actual executable project.
The simple answer is to pull the functions in util.obj into their own library and have your library and the executable link it.
If you only need the utility functions in a single source file, you can move them into the .c file and declare them static, then they won't have any linkage outside the file they're defined in.
If you really want to do it by not exporting symbols, mark the function with __declspec(selectany), which will tell VS that multiple definitions of the function are equivalent and it's free to choose whichever it likes (make sure they're actually the same!).
So, figured it out: if you use the pragma statement it will integrate the functions into your static library. In my case I put:
#pragma comment(lib, "libev.lib")
in a header and it imported libev into my library. Now when I actually wrote my executable I only needed to link against my library: there is no additional libev dependency.

Resources