C++/CLI exporting global symbols in assembly - c++-cli

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.

Related

How to handle 'Object': ambiguous symbol in Visual Studio

I am creating a C++/CLI wrapper for native C code that has it's own Object typedef and am receiving the C2872 'Object': ambiguous symbol error when linking. The compiler output is:
1>C:\src\OS_kernel.h(27): error C2872: 'Object': ambiguous symbol
1>C:\src\OS_types.h(261): note: could be 'ObjectStruct *Object'
1>C:\src\OS_kernel.h(27): note: or 'System::Object'
It may be worth mentioning that I am mocking this native C code for the purposes of the C++/CLI wrapper; not sure if that opens up a potential solution that would otherwise not be available if no source code was available. I'm guessing there is a way to specify which definition I want the code to use, but I don't know how to specify that. Is that possible? I want to specify it to use the ObjectStruct *Object.
It would be great if I didn't have to modify the mock code since it could potentially be hundreds or thousands of individual places.
As an aside, I am also receiving this error for other types the native library is using, such as Buffer and Boolean.
OK, since you're getting the error in OS_kernel.h, I'm guessing that's part of the C code you're wrapping.
Obviously, one possible solution is to treat the name Object as a reserved word, and edit your C code to not use it. One could argue that this is the most correct solution, but it may not be possible to do that.
Depending on how you're referencing the C code, it may be reasonable to compile it as C++, and stick it entirely within a namespace. That way, when the C code (now C++ code) uses Object it will see the typedef within its namespace, and you'll have the option to reference either namespace in your code.
The fact that you're getting this error from your library's header file indicates to me that you've got a using namespace System; directive, and that the #include of your library's header files comes after that using directive. Consider removing the using namespace System;, or at least moving it after the #include. This way, you won't get that error in the library's headers, you'll just have to deal with it in your code.

Is there a conventional URI scheme for referencing code in a library?

Is there a standard or conventional URI scheme, like file: or http: for referencing objects in a dynamic library?
For example, if I were to represent a function in a library in the form of a unique string that can be used to look up that function (by whatever reflective means), how might I do that?
Specifically I'm developing this in Objective-C, and I assume different languages/platforms will have different representations (I know .NET has its own), but I'm curious about this in a more general sense.
No, the name of the symbol is derived from its name in your code. In windows you will assuming C or C++
HMODULE module=LoadLibrary( [path to your dll] );
//If the exported name is foo.
Function foo=(Function)GetProcAddress(module,"foo");
//Call function
foo();
FreeLibrary(module);
The exported name is compiler-dependent.
Acually such a naming scheme is quite useless. In C++ you can use something like (Note that you will have one FunctionCaller per function prototype)
FunctionCaller("your-dll.dll/foo")();
Where the constructor of FunctionCaller loads the library, calls foo and frees the library. However it is not good because:
it may happen that the return value points to a resource inside the library and then will become useless
loading libraries and perform function look-up is slow relative to calling the function found
What you do is
Load the library
Load functions that you will need
Use your functions
Free the library
Here you would need to refer to more than one symbol at a time which would require a more complex scheme than uri.
EDIT: If you want to the convenience of calling functions like that you could have a surviving FunctionCaller object that keeps all loaded modules and contains a map from function name to address for each loaded library.

What are Modules when creating COM objects with Embarcadero C++ Buider

I am creating a COM library with Embarcadero C++ Builder. The designer for the ridl file gives several things you can add to the ridl. I think I understand all of them except for creating new "Modules". I can't find good information for it in the documentation.
What is a "Module" and what would it be used for in COM?
You say you can't find 'good information' in the documentation; what have you found? The RAD Studio help has a section specifically explaining modules, which says:
A module defines a group of functions,
typically a set of DLL entry points.
You define a module by
Specifying a DLL that it represents on the attributes page.
Adding methods and constants using the toolbar or the object list pane
context menu. For each method or
constant, you must then define its
attributes by selecting the it in the
object list pane and setting the
values on the Attributes page.
For module methods, you must assign a
name and DLL entry point using the
attributes page. Declare the
function's parameters and return type
using the parameters page.
For module constants, use the
Attributes page to specify a name,
type, and value.
Note: The Type Library Editor does not generate any declarations or
implementation related to a module.
The specified DLL must be created as a
separate project.
It seems it's specifying methods that exist in an external DLL to whatever module (EXE or DLL) the type library is built into. Exactly what that's used for... is a good question.
The module attribute is described in this MSDN Library page. It permits declaring entrypoints in a DLL. That has little to do with COM, it is just a capability of a type library. You'll find few language development environments that can use them. I think VB6 was one of them. Ymmv.

interface of dll

I heard people talking about changing the interface of a dll.
What is a change in the interface of the dll, and how would you do that?
Changing a dll's interface would mean to change how the dll and the calling code interacts. This could mean changing the signatures of the dll's exporting functions, or changing to a different set of functions entirely, or it could mean passing different data from the calling code. A dll's interface is generally all it's exported and imported items (both functions and data), or in other words, the parts of the dll that you have access to when you use it.
Often you will want to change the behaviour of your dll without changing its interface. This is because changing the interface often will break code that uses it.
Imagine my dll exporting function foo:
void foo(int i)
{
// Does thing with integer
}
Changing the interface could mean changing foo's signature into
void foo(int, float);
Now, all the code that used foo previously has to be rewritten to use the new signature, which could be a bad thing.

How to update a C++ dll without needing to relink the exe with the lib file?

First off , I'm referring to a Windows environment and VC++ compiler.
What I want to be able to do is rebuild a Vc++ dll and maintain compatability with an exe that has already been linked to the lib without having to rebuild the exe or load the dll dynamically using LoadLibrary. In other words, is there a way to add classes and methods to a dll(but not remove any) and ensure the existing entrypoints remain the same?
If you export the functions from using a DEF file and manually specify the ordinals, you should be able to accomplish this.
Reference
http://msdn.microsoft.com/en-us/library/d91k01sh(VS.80).aspx
It depends on how your EXE used the classes from the DLL. Adding new classes should not affect existing entrypoints. Aside from that, however, any the following will affect object size and/or layout, and as such will be a client-breaking change (note that this is technically VC-specific, but most of these apply to any sane implementation):
Removing fields (even private) from classes
Adding new fields (even private) to classes
Adding new base classes to existing classes
Removing base classes from existing classes
Adding new virtual method before an existing virtual method (adding new virtual methods after existing ones is okay, except for the case described in next point)
Adding a new virtual method in a class that is used as base class by another class in the same DLL which also has virtual methods
Changing type of existing fields
Changing signature of existing methods
Making a virtual method non-virtual, and vice versa
As long as you don't add any exported symbols, the ordinals won't change. If you add exported symbols through the standard dllexport mechanism, then that's going to be difficult to control. If you use the old style .xpf symbol file you might be able to control the ordering of the symbols in the lib (although I don't know this for sure - it might still reorder them however it likes), but it's tricky to do C++ symbols this way.
I think that ordinals are rarely used to resolve DLL imports anymore - I think that you have to use .def files to get the linker to use them. So as long as you don't change names or signatures of the exported functions, the .exe should work just fine.