Export Functions of DLL's as seen by depends - dll

I was looking over the list of functions that were exported from a dll using depends and i noticed some weird symbols included with the names. They are of the format
??0Function Name##QEAA#AEBV0##Z
Also 0 maybe replaced by some other number.
The number of ## and the alphabets vary.
Can anybody tell what they represent?

That's the name of a C++ identifier that was decorated by the C++ compiler. You can run the undname.exe utility from the Visual Studio Command Prompt to convert it back to the original C++ declaration:
C:\>undname ??0Foo##QEAA#AEBV0##Z
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.
Undecoration of :- "??0Foo##QEAA#AEBV0##Z"
is :- "public: __cdecl Foo::Foo(class Foo const & __ptr64) __ptr64"
Which makes it the copy constructor for the Foo class, compiled to 64-bit code. The exact decoration algorithm is not documented that I know of. In general, name decoration is used to avoid linker symbol collisions, necessary because C++ supports overloading. You can suppress decoration by using extern "C" but that can't work on a C++ class.

In some situations you might be interested to undecorate these names programatically using an API Microsoft is providing UnDecorateSymbolName.

Related

C++/CLI exporting global symbols in assembly

I've got a situation where I can't change a CLI header that declares several symbols in the global scope, and then those symbols are then used by a function which IS inside a namespace, and that function is exported in an assembly I need to make use of.
Below is a bit of puedo code to help illustrate the Visual Studio setup. Also, I'm using the 2008 toolchain which is pre C++11 making the 'enum class' a managed object. Also note that it also doesn't have the access specifier (I did not write this) which makes it private.
ExportingAssembly.vcxproj
|->SomeHeader.h
| |->enum class SomeSymbol
|->SomeSource.c
|->SomeNamespace
|->void SomeFunction(SomeSymbol arg)
ImportingAssembly.vcxproj
|->Ref ExportingAssembly
|->ImportingSource.c
|->Using SomeNamespace;
|->void MyFu(){ SomeSumbol a = 0; SomeFunction(a); }
The problem is that those global symbols are obviously not visible to the importing assembly and if I include the header for those symbols it results in an incompatibility between my assembly and the one I'm importing
error C2664: 'ExportAssemblyNamespace::SomeFunction(SomeSymbol arg)': can't
convert parameter 1 from 'SomeSymbol" to 'SomeSymbol'
Now I CAN change the exported assembly (the project file and/or the source file) so I just hope I can somehow make those global symbols part of the exported assemblies' namespace so the importing assembly will see them. Or failing that, somehow locate the global symbols in the exported assembly (I can see the global symbols are in the PE MetaData Tables).
Any ideas. Or is a symbol without an access specifier private and impossible to make use of via referencing the assembly?
Or is a symbol without an access specifier private and impossible to make use of via referencing the assembly?
Yes, a symbol without an access specifier is private. It's not quite "impossible" to make use of; the only way is via reflection.
The fact that you have some things in a namespace, and some not, doesn't matter here. But you should have your function as part of a class, since global functions aren't part of the CLR. (C++/CLI creates a class to hold the global functions, but it's not a public class, and I think it has an invalid name anyway.)
Add the keyword public to your enum, and enclose your function in a public ref class.

Is C++/CLI an extension of Standard ISO C++?

Is Microsofts C++/CLI built on top of the C++ Standard (C++98 or C++11) or is it only "similar" and has deviations?
Or, specifically, is every ISO standard conforming C++ program (either C++98 or C++11), also a conforming C++/CLI program?
Note: I interpret the Wikipedia article above only comparing C++/CLI to MC++, not to ISO Standard C++.
Sure, it is an extension to C++03 and can compile any compliant C++03 program that doesn't conflict with the added keywords. The only thing it doesn't support are some of the Microsoft extensions to C++, the kind that are fundamentally incompatible with managed code execution like __fastcall and __try. MC++ was their first attempt at it, kept compatible by prefixing all added keywords with underscores. The syntax was rather forced and not well received by their customers, C++/CLI dropped the practice and has a much more intuitive syntax. Stanley Lippman of C++ Primer fame was heavily involved btw.
The compiler can be switched between managed and native code generation on-the-fly with #pragma managed, the product is a .NET mixed-mode assembly that contains both MSIL and native machine code. The MSIL produced from native C++ source is not exactly equivalent to the kind produced by, say, the C# or VB.NET compilers. It doesn't magically become verifiable and doesn't get the garbage collector love, you can corrupt the heap or blow the stack just as easily. And no optimizer love either, the MSIL gets translated to machine code at runtime and is optimized just like normal managed code with the time restrictions inherent in a jitter. Getting too much native C++ code translated to MSIL is a very common mistake, the compiler hides it too well.
C++/CLI is notable for introducing syntax that got later adopted into C++11. Like nullptr, override, final and enum class. Bit of a problem, actually, it begat __nullptr to be able to distinguish between a managed and a native null pointer. They never found a great solution for enum class, you have to declare it public to get a managed enum type. Some C++11 extensions work, few beyond the ones it already had, auto is fine but no lambda expressions, quite a loss in .NET programming. The language has been frozen since 2005.
The C++/CX language extension is notable as well, one that makes writing C++ code for Store and Phone apps palatable. The syntax resembles C++/CLI a great deal, including the ref class and hats in the syntax. But with objects allocated with ref new instead of gcnew, the latter would have been too misleading. Otherwise very different from C++/CLI at runtime, you get pure native code out of C++/CX. The language extension hides the COM interop code that's underneath, automatically reference-counting objects, translating error codes into exceptions and mapping generics. The resemblance to C++/CLI syntax is no accident, they basically perform the same role. Mapping C++-like syntax to a foreign type system.
CLI is a set of extensions for standard C++. CLI has full support of standard C++ and adds something more. So every C++ program will compile with enabled CLI, except you are using a CLI reserved word and this is the weakness of the extension, because it does not respect the double underscore rule for extensions (such reserved words has to begin with __).
You can deactivate those extensions in the GUI by:
Configuration Properties -> General -> Common Language Runtime Support
Even Bjarne Stroustrup calls CLI an extension:
On the difficult and controversial question of what the CLI binding/extensions to C++ is to be called, I prefer C++/CLI as a shorthand for "The CLI extensions to ISO C++". Keeping C++ as part of the name reminds people what is the base language and will help keep C++ a proper subset of C++ with the C++/CLI extension
Language extensions could always be called deviations from the standard, because it will not compile with a compiler without CLI support (e.g. the ^ pointer).

Including headers from an unmanaged C++ code inside C++/CLI code

I'm writing a CLR wrapper for an unmanaged C++ library.
There are two files I'm including from the unmanaged lib:
//MyCLIWrapper.h
#include "C:\PATH\TO\UNMANAGED\Header.h"
#include "C:\PATH\TO\UNMANAGED\Body.cpp"
Then I'm writing CLI implementations for the unmanaged library functions:
//MyCLIWrapper.h
// includes ...
void MyCLIWrapper::ManagedFunction()
{
UnmanagedFunction(); // this function is called successfuly
}
However, if my Unmanaged function contains calls to other functions that are defined in other unmanaged header files. This causes a compiler linkage error.
If I add includes to the unmanaged headers that define these functions, my errors get resolved. However, there is a lot of functions, and a lot of includes required.
Is there a different way to approach this?
EDIT:
P.S.
My managed code is in a separate Visual Studio project (output - DLL), and the compile settings are set to /CLR. Unmanaged code is in a separate Win32 project (output - DLL).
Also, after more research I concluded that theoretically I could set my Win32 unmanaged project to CLR and just add my managed classes and headers in there as an entry point, and then it would all compile into a single DLL file. That would probably solve (?) the linkage errors. However, I would prefer to preserve the loose coupling as well as the additional series of problems that can raise from setting my unmanaged project to CLR.
EDIT #2:
The unmanaged class that I'm referencing (body.cpp, header.h) contains includes to the required files that define the functions that are causing the problems. However, my managed code doesn't pick up on the includes that are in the unmanaged body.cpp and header.h.
Linker errors are a different kettle of fish from compiler errors. You forgot to document the exact linker errors you see, but a very common mishap when you compile code with /clr in effect is that the default calling convention for non-C++ member function changes. The default is __clrcall, a convention that's optimized for managed code. While functions compiled without /clr defaults to __cdecl. Which changes the way the function name is mangled. You see this back in the linker error message, is shows that it is looking for a __clrcall function and can't find it.
You'll need to either explicitly declare your functions in the .h file with __cdecl. Or tell the compiler that these functions are not managed code. Which is the best way to tackle it:
#pragma managed(push, off)
#include "unmanagedHeader.h"
#pragma managed(pop)
Solution was fairly simple:
I added both unmanaged and managed projects to a single solution in Visual Studio.
Set the unmanaged project's "Configuration Type" to "Static Library" (.lib).
Right click on the managed project -> References -> Add Reference -> Projects -> -> Add Reference.
Then in my managed class, I include the header.h (only) just like I did in my question.
Compiled successfully!
Thank you

Linker error when calling function in native C++ from a c++/cli project

I am trying to call functions in c++ from C# and to do this, I created a C++/CLI project to wrap C++ codes.
My code compiles, but during linkage, I am getting error that linker can not find methods which are defined in c++ code.
The c++ code is a static library and I add a reference to it in C++/CLI project (common properties -> framework and references -> add new reference)
My questions:
Is there anything else should I do?
is adding reference in this sections means that the reference is a .net assembly? Or could it be a reference to a static library.
Edit 1
I am sing VS 2012 on windows 7 64bit
Linker Error:
Error 3 error LNK2019: unresolved external symbol "public: static class MyFile __cdecl MyFile::ReadMyFile(char *)" (?ReadMyFile#MyFile##$$FSA?AV1#PAD#Z) referenced in function "public: static class MyFileWrapper::MyFileWrapper ^ __clrcall MyFileWrapper::MyFileWrapper::ReadMyFile(class System::String ^)" (?ReadMyFile#MyFileWrapper#1#$$FSMP$AAV11#P$AAVString#System###Z) MyFileWrapper.obj
You didn't post the linker error message, that makes it difficult to answer this question accurately. The most common causes:
Forgetting to tell the compiler that the function is a native function and not a managed one. You can tell from the linker error message when you see it using the __clrcall calling convention, native code normally uses the __cdecl calling convention. You fix that by putting #pragma managed(push, off) before the #include, #pragma managed(pop) after it.
Trying to link a static library that was compiled with /clr in effect. That's not supported without otherwise drawing a complaint about that when you build the library, unfortunately. The equivalent is already well supported by the CLR, it binds libraries at runtime. You fix that by creating a class library project instead so you'll get a DLL after building it. Use Add Reference to import the declarations from that assembly instead of using #include.
Forgetting to tell the linker that it needs to link an unmanaged static library or import library. Using Add Reference is supported in VS2010 and up, on earlier versions of VS you need to use the Linker, Input, Additional Dependencies setting or use #pragma comment(lib, "name") in your source code.
$$F part of the given mangled name is a marker of function modifier , that means managed function [Managed C++ or C++/CLI], according to "Visual C++ name mangling".
I faced very similar problem. I figured out that in my case there was:
<ProjectReference Include="ProjName\ProjName.vcxproj">
<ProjectReference Include="..\ProjName\ProjName.vcxproj">
I've just fixed that and made rebuild and it helped me.

Why do we still need a .lib stub file when we've got the actual .dll implementation?

i'm wondering why linkers can not do their job simply by consulting the information in the actual .dll files that got the actual implementation code ? i mean why linkers still need .lib files to do implicit linking ?
are not the export and relative address tables enough for such linking ?
is there anyway by which one can do implicit linking using only the .dll without the .lib stub/proxy files ?
i thought the windows executable loader would simply do LoadLibrary/LoadLibraryEx calls on behalf of the program (hence the name implicit linking) which is the main difference to explicit linking. if that is true then doing it explicitly without .lib should indicate that it is doable without it implicitly, right ? or i'm just saying non sense?
I can think of a a few reasons.
Using .lib files mean you can build for a different version of a DLL than you have on your system, provided you just have the correct SDK installed.
Compilers & linkers need to support cross-platform compilations - You might be building for a 64-bit target on a 32-bit platform and vice-versa and not have the correct architecture DLL present.
.lib files enable you to "hide" certain parts of your implementation - you could have private exports that do not show up in the .lib but are discoverable via GetProcAddress. You can also do ordinal exports in which case they don't have a friendly name exported, but would have a friendly name in the .lib.
Native DLL's do not have strong names, so it may be possible to pick up the wrong version of the DLL.
And most importantly, this technology was designed in the 1980's. If it were designed today, it'd probably be closer to what you describe - for instance, .NET you just need to reference the target assembly and you have everything you need to use it.
I don't know of any way to do implicit linking solely with the DLL - A quick search revealed several tools, but I haven't used any of them.
In this case, I would create a separate source file with the functions you need to use, and dynamically load the DLL and bind them as needed. For example:
// using global variables and no-error handling for brevity.
HINSTANCE theDll = NULL;
typedef void (__stdcall * FooPtr)();
FooPtr pfnFoo = NULL;
INIT_ONCE initOnce;
BOOL CALLBACK BindDLL(PINIT_ONCE initOnce, PVOID parameter, PVOID context)
{
theDll = LoadLibrary();
pfnfoo = GetProcAddress(dll, "Foo");
return TRUE;
}
// Export for foo
void Foo()
{
// Use one-time init for thread-safe lazy initialization
InitOnceExecuteOnce(initOnce, BinDll, NULL, NULL)
pfnFoo();
}