C++ does not import class methods from DLL while importing functions works fine - class

I am trying to import a DLL to my program. I am using the __declspec( dllimport ) attribute. The problem is I get the linker error "LNK2019: unresolved external symbol ...". This question has already been around here several times. But my problem is different.
I believe I have all the things set up correctly (header provided, lib-file with the exports linked in ...). When I try call a classic function (with or without extern "C" block) from that DLL, all works fine. The problem are just the classes.
All the method are exported within the DLL - I verified this by using the Dependency Walker.
Can there be some mismatch between the mangled exported names and the ones the linker tries to find? Or some other naming based problem? It seems there is no similar problem documented over the internet.
EDIT
The dependency walker sees the method
?LoadFile#CTxtFileHelper##QAE_NPAVCWrapperFile##I#Z
which is unmangled
bool CTxtFileHelper::LoadFile(class CWrapperFile *,unsigned int)
while the linker is trying to load the
?LoadFile#CTxtFileHelper##QAE_NPAVCWrapperFile#io#mylib##I#Z
which represents according to linker error message
__declspec(dllimport) public: bool __thiscall CTxtFileHelper::LoadFile(class mylib::io::CWrapperFile *,unsigned int)
The only difference is the namespace. Can it be the problem?
Thanks

Related

Why it compiles with different type?

Error:
IL2CPP error for type 'Namespace.SubNamespace.MyClass/<MyIEnumeratorFunc>d__20' in assembly 'Path\MyUnityProject\Temp\StagingArea\Data\Managed\VisualStudioSolutionName.dll'
Additional information: Interface System.Collections.Generic.IEnumerator`1<System.Object> method T System.Collections.Generic.IEnumerator`1<System.Object>::get_Current() not implemented on non-abstract class Namespace.SubNamespace.MyClass/<MyIEnumeratorFunc>d__20
Unity expect System.Collections.IEnumerator and I try to use IEnumerator:
I tried to write directly
private System.Collections.IEnumerator MyIEnumeratorFunc(){}
I tried to remove
using System.Collections.Generics;
and append it to each List/Dictionary entry
Everything works in Editor, but I get error I described above:
Seems like it tries to use System.Collections.GENERICS.IEnumerator.
Also, the error disappears if I use source code (not .dll)
Also, you can reproduce it by creating .dll with any IEnumerator/async function (even empty) and build for iOS.
The problem was in Project name.
Solution is
Right mouse click on Project name (not solution name) in Solution Explorer.
Properties
"Application" tab
Assembly name -> set to the same to .dll file name (without ".dll")

Reimplimenting a DLL method variable with C++ in visual studio at ABI level

I have a third party DLL in C++ that I'd like to replace with one I've made myself...
This is a clean room type exercise just for learning purposes ; and I am hoping to make a replacement DLL that can be used with programs linked against the original DLL -- without recompiling the applications.
I am using the same visual studio compiler version (9) used to make the original DLL, but I do not have the original source code for the DLL.
The DLL consists of a C++ class, and some extern "C" functions to handle constructor/destructors, so that all memory management is isolated to the DLL.
I used dependency walker to inspect the original DLL, and demangle/undecorate the linker symbols -- and have attempted to write prototypes for the class and methods ; and then I wrote a python script to take the object code compiled from my class -- and make a .def file that chooses the closest mangled symbols from MY obj code compared against the original DLL exports; ( Allows some qualifier variations, but not name variations ) and then I build a DLL from my obj code using that .def file to have an identical ABI ordering in the DLL.
I am at the stage where dependency walker can not tell the difference between my DLL and the original when it comes to listing the types -- although there are small differences in several of the mangled names that I would like to resolve...
One member is very troublesome to figure out as it is not a function, but supposedly member data eg: a decorated ?pzSambaAddress#HWInterface##2PBDB shows up as:
char const * const HWInterface::pzSambaAddress ; // in dependency walker
And I'm not sure if dependency walker is decoding the mangling wrong or not, because
I can't figure out how to implement anything even remotely like this in my header file which would export a symbol to an .obj file, let alone to a DLL.
What kinds of definitions could create something like that?
If I type it in (as shown above) to my header file, it's a constant string -- therefore I'm thinking it has to be initialized in the constructor methods, something like this:
HWInterface::HWInterface(HWInterface const & iface) : pzSambaAddress("dummy") {
std :: cout << this -> pzSambaAddress; // access it, to force compiler
}
But when I compile that, pzSambaAddress, does not show up in the obj file at all.
Obviously because it's not an allocated memory location prior to class instantiation.
eg: dumpbin /SYMBOLS HWInterface.obj | grep "pzSam" finds nothing.
I could add the static keyword to the definition of pzSambaAddress and initialize it exactly once for the whole class.
char const * const HWInterface::pzSambaAddress="a samba name constant.";
The name then mangles to: ?pzSambaAddress#HWInterface##2QBDB
But dependency walker doesn't say it's static... Nor is mangled ##2QBDB quite ##2PBDB... and that will also mean that I can also no longer initialize individual instances with constructors.
HWInterface.cpp(25) : error C2438: 'pzSambaAddress' : cannot initialize static class data via constructor
So Q1: Is a static constant the cause of the exported symbol, and dependency walker just doesn't say "static" -- or are there other ways it could be generated / initialized ?
Secondly:
Is there anything better at demangling, and giving information on esoteric qualifiers?
When I run dumpbin on an object file, I get all kinds of qualifiers that dependency walker doesn't show (on other symbols, not the example we've been talking about).
dumpbin.exe /symbols myOwnFile.obj
But as I don't have the obj file for the original DLL, nor the .lib, that switch doesn't work. Running dumpbin.exe /symbols on the DLL gives me nothing.
Running dumpbin.exe /exports on the DLL merely gives me the mangled names.
There is also a VC++ console application "undname.exe", but often it doesn't undecorate the name passed on the command line at all, but gives most of the name back still mangled.
I looked around a lot on the web, but am finding only partially accurate/incomplete information, which wasn't enough to solve the problem I just showed.
Wikipedia on mangling names
Any ideas of where to find a more verbose/accurate demangler program for visual C++ ?
class HWInterface {
public:
__declspec(dllexport)
static char const * pzSambaAddress;
};
char const* HWInterface::pzSambaAddress = "hello";
Then:
C:\temp>cl /LD test.cpp
...
C:\temp>dumpbin /exports test.dll
...
Dump of file test.dll
...
ordinal hint RVA name
1 0 00008000 ?pzSambaAddress#HWInterface##2PBDB
You can use the undname utility included with MSVC to decode mangled names:
C:\temp>undname ?pzSambaAddress#HWInterface##2PBDB
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.
Undecoration of :- "?pzSambaAddress#HWInterface##2PBDB"
is :- "public: static char const * const HWInterface::pzSambaAddress"
However, you'll note that undname says that there should be an extra const in there. As you saw, adding that extra const gets you a slightly different mangled name (with a 'Q' instead of a 'P' near the end:
Using static char const * const instead of static char const * produces ?pzSambaAddress#HWInterface##2QBDB
undname imports a function from the C runtime, _unDNameEx, that I assume is used to demangle names (and I assume that Dependency Walker uses it, too - apparently via an interface in DBGHELP.DLL). Looks like there's a bug in the demangler.
The GNU tools have a similar utility, c++filt, to decode g++ mangled names.

iOS - expected '=', ',', ';', 'asm' or '__attribute__' before typedef [duplicate]

I'm trying to port the speakhere example into another app and I'm having issues. I copied all the files, and all the frameworks, but for some reason I get a bunch of compile errors that I've never seen before and thus don't know what to do. The only difference is that i'm not suing IB and so i had to change it slightly.
What does error: expected '=', ',', ';', 'asm' or '__attribute__' before 'foo' mean?... I get this error multiple times for different files
In my situation the first error is pointing at 'MeterTable'.. a class that includes <stdlib.h>,<stdio.h> and <math.h>. But those files seem to be importing fine (if i remove them i get more errors)
Any suggestions on how to debug this?
TIA!
EDIT:
I still can't seem to figure it out. I'm literally just copying files from the example into another project. Can someone check it out please ? SpeakHerePort.zip and the original is here SpeakHere.zip
Your problem is that you are compiling SpeakHerePortAppDelegate.m, which is an Objective C file, but it is indirectly including MeterTable.h which is a C++ header file.
Rename it to SpeakHerePortAppDelegate.mm (double m) so that it is compiled as Objective C++ and your problem is resolved.
Name all your files .mm and then all your code will be compiled as Objective C++
In my case, the .h and .m in question are built fine with regular target, and the App can run as well.
However after the subset of the files are moved under a static library target, it gets this compile error when the static library is built.
Was stuck for a while & tried the above mentioned techniques, unfortunately they didn't help in my case.
Noted that this error happened only for the NSString*, for e.g.,
extern double const kTimeout; // fine
extern NSString* const kImageType; // compile error
After the above analysis & little break, eventually the problem is resolved by adding the the following import to the .h - "Foundation/Foundation.h"
It sounds like an unfinished declaration, probably in a header file. Search for 'foo' (or whatever the symbol actually is) across all project files, using ⇧⌘F (Edit ▸ Find ▸ Find In Project...) in Xcode, and/or examine the headers you're including where MeterTable is declared. Sometimes the compiler gets confused about the actual location of the error, since header files are frequently #imported into other files, so the problem can be manifest in multiple locations.
This might not have applied to this exact situation, but I had this exact error too, which was caused by a bad forward declaration. In Objective-C, make sure your forward-declares begin with the # sign - e.g.
#class MyClass;
Those of us still on autopilot from C++ will forget the #, see that XCode has highlighted class as a reserved keyword, and think all is well with the world. It is not.
It means that you have a syntax error. If you paste the code in question, it's easier to debug.
I had a similar scenario to some of the posts above. I'd written a C++ class based off of the examples in the Audio Queue Services documentation, and had this compilation issue in a test project. This post helped a tremendous amount.
Today, I'm incorporating the C++ class in my project, and got the build error again. In my scenario, I had to also set the type (using the "Get Info" window) to sourcecode.cpp.objcpp for the objective-c class that was calling my C++ class.

Need clarification on what's going on when linking libraries in iOS

This is probably a totally noob question but I have missing links in my mind when thinking about linking libraries in iOS. I usually just add a new library that's been cross compiled and set the build and linker paths without really know what I'm doing. I'm hoping someone can help me fill in some gaps.
Let's take the OpenCV library for instance. I have this totally working btw because of a really well written tutorial( http://niw.at/articles/2009/03/14/using-opencv-on-iphone/en ), but I'm just wanting to know what is exactly going on.
What I'm thinking is happening is that when I build OpenCV for iOS is that your creating object code that gets placed in the .a files. This object code is just the implementation files( .m ) compiled. One reason you would want to do this is to make it hard to see the source code and so that you don't have to compile that source code every time.
The .h files won't be put in the library ( .a ). You include the .h in your source files and these header files communicate with the object code library ( .a ) in some way.
You also have to include the header files for your library in the Build Path and the Library itself in the Linker Path.
So, is the way I view linking libraries correct? If , not can someone correct me on this ?
Basically, you are correct.
Compiling the source code of a library produces one object file for each of the source files (in more than one, if compiled multiply times against different architectures). Then all the object files are archived (or packaged) into one .a file (or .lib on Windows). The code is not yet linked at this stage.
The .h files provide an interface for the functionality exposed by the library. They contain constants, function prototypes, possibly global declarations (e.g. extern int bad_global;), etc. -- basically, everything that is required to compile the code which is using the library.
.h files do not 'communicate' with object code in any way. They simply provide clues for the compiler. Consider this header file:
// library.h
extern int bad_global;
int public_func(int, const void*);
By including this file in your own code, you're simply telling the compiler to copy and paste these declarations into your source file. You could have written declarations for OpenCV library and not use the headers provided with it. In other words, you're asking the compiler to not issue errors about undefined symbols, saying "I have those symbols elsewhere, ok? Here are their declarations, now leave me alone!".
The header files need to be included in the search path in order for compiler to find them. You could simply include them via the full path, e.g. #include "path/to/file.h", or supply an -I option for your compiler, telling him where to look for additional headers, and use #include <file.h> instead.
When your code is compiled, the declarations in header files serve as an indication that symbols your code is using are defined somewhere. Note the difference between the words declaration and definition. Header files contain only declarations most of the time.
Now, when your code is compiled, it must be linked in order to produce the final executable. This is where the actual object code stored in the library comes into play. The linker will look at each symbol, function call, etc. in your object code and then try to find the corresponding definition for each such symbol. If it doesn't find one in the object code of your program, it will look the standard library and any other library you've provided it with.
Thus, it is important to understand that compilation and linkage are two separate stages. You could write any function prototypes at all and use them in your code, it will compile cleanly. However, when it comes to the linking stage, you have to provide implementation for symbols used in your code, or you won't get your executable.
Hope that makes sense!
The .a is the compiled version of the code.
The header files provided with a library are its public interface. They show what classes, methods, properties are available. They do not "communicate" with the binary code.
The compiler needs the headers to know that a symbol (a method name for example) is defined somewhere else. They are associated with the right "piece of code" in the library binary later during the "link" step.

iphone error: expected '=', ',', ';', 'asm' or '__attribute__' before ' 'foo'

I'm trying to port the speakhere example into another app and I'm having issues. I copied all the files, and all the frameworks, but for some reason I get a bunch of compile errors that I've never seen before and thus don't know what to do. The only difference is that i'm not suing IB and so i had to change it slightly.
What does error: expected '=', ',', ';', 'asm' or '__attribute__' before 'foo' mean?... I get this error multiple times for different files
In my situation the first error is pointing at 'MeterTable'.. a class that includes <stdlib.h>,<stdio.h> and <math.h>. But those files seem to be importing fine (if i remove them i get more errors)
Any suggestions on how to debug this?
TIA!
EDIT:
I still can't seem to figure it out. I'm literally just copying files from the example into another project. Can someone check it out please ? SpeakHerePort.zip and the original is here SpeakHere.zip
Your problem is that you are compiling SpeakHerePortAppDelegate.m, which is an Objective C file, but it is indirectly including MeterTable.h which is a C++ header file.
Rename it to SpeakHerePortAppDelegate.mm (double m) so that it is compiled as Objective C++ and your problem is resolved.
Name all your files .mm and then all your code will be compiled as Objective C++
In my case, the .h and .m in question are built fine with regular target, and the App can run as well.
However after the subset of the files are moved under a static library target, it gets this compile error when the static library is built.
Was stuck for a while & tried the above mentioned techniques, unfortunately they didn't help in my case.
Noted that this error happened only for the NSString*, for e.g.,
extern double const kTimeout; // fine
extern NSString* const kImageType; // compile error
After the above analysis & little break, eventually the problem is resolved by adding the the following import to the .h - "Foundation/Foundation.h"
It sounds like an unfinished declaration, probably in a header file. Search for 'foo' (or whatever the symbol actually is) across all project files, using ⇧⌘F (Edit ▸ Find ▸ Find In Project...) in Xcode, and/or examine the headers you're including where MeterTable is declared. Sometimes the compiler gets confused about the actual location of the error, since header files are frequently #imported into other files, so the problem can be manifest in multiple locations.
This might not have applied to this exact situation, but I had this exact error too, which was caused by a bad forward declaration. In Objective-C, make sure your forward-declares begin with the # sign - e.g.
#class MyClass;
Those of us still on autopilot from C++ will forget the #, see that XCode has highlighted class as a reserved keyword, and think all is well with the world. It is not.
It means that you have a syntax error. If you paste the code in question, it's easier to debug.
I had a similar scenario to some of the posts above. I'd written a C++ class based off of the examples in the Audio Queue Services documentation, and had this compilation issue in a test project. This post helped a tremendous amount.
Today, I'm incorporating the C++ class in my project, and got the build error again. In my scenario, I had to also set the type (using the "Get Info" window) to sourcecode.cpp.objcpp for the objective-c class that was calling my C++ class.