Рассмотрим второй способ устранения препятствий, вызванных декорацией имен. Для того, чтобы реализовать его надо возвратиться к серверному проекту MyDLL, вставить в нужные места описатель extern "C" (именно он отменяет декорацию имен) и построить DLL заново. Кроме отмены декораций, этот описатель заменяет способ передачи параметров, вместо __cdecl он становится __stdcall. При этом прежний клиент (на языке С++) перестанет работать. Клиентское приложение тоже придется перестроить, введя исправления, то есть вставить в нужные места описатели extern "C".
Подведем итог, вы открываете проект MyDLL и либо вставляете много описателей extern "C", например,
extern "C" __declspec(dllexport) void AllocMatrix (double**& a, int ny, int nx)
{
// Код функции AllocMatrix
}
extern "C" __declspec(dllexport) void ClearMatrix (double**& a, int n)
{
// и т.д. перед каждой экспортируемой сущностью либо заключаете все экспортируемые сущности в один большой блок:
extern "C"
{
// Здесь расположены все экспортируемые сущности
}
Это надо сделать как в серверном проекте, так и в клиентском проекте на языке С++ (если вы хотите, чтобы он продолжал работать). В проекте на языке C# надо вернуться к первому способу вызова функций (по именам). После этого все проекты должны работать. Трудно проделать все это без ошибок, но делать все равно надо, хотя бы для того, чтобы убедиться в своей квалификации (или в том, что перед тем как принять важное архитектурное решение, надо очень тщательно продумать все детали). Мне не нравятся все эти заплаты, но я понимаю, что их необходимость была заложена давно и из хороших побуждений.
Characteristic |
COM Model |
.NET Framework Model |
Coding model |
Interface based |
Object based |
Identity |
GUIDs |
Strong names |
Type compatibility |
Binary standard |
Type standard |
Type definition |
Type library |
Metadata |
Type safety |
Not type-safe |
Optionally safe |
Error-handling mechanism |
HResults |
Exceptions |
Object-lifetime management |
Reference counting |
Garbage collection |
Versioning |
Immutable |
Resilient |
Strong names consist of a unique assembly name in addition to a type name. Because the assembly name uniquely identifies the type, you can reuse a type name across multiple assemblies. An assembly also introduces publisher key, version, and location information to a managed type.
¨ In COM Model type information is stored only for public types. Moreover, a type library is optional.
¨ In .NET Framework Model type information is stored as metadata (which is embedded inside assemblies) and is mandatory for all types.
¨ COM interfaces are immutable. If you change an interface, you must rename it with a new GUID.
¨ Versioning in .NET Framework Model is resilient — managed types can evolve, retaining the same name.
The CLR enables managed code to call COM objects through a proxy called the Runtime Callable Wrapper (RCW). When a .NET Client loads a COM object, a runtime callable wrapper (RCW) is created. The runtime creates exactly one RCW for each COM object, regardless of the number of references that exist on that object. This ensures that a single object identity is shared between the RCW and the COM object. The RCW is a managed object and subject to garbage collection. The primary goal of the RCW is to hide the differences between the managed and unmanaged programming models. .NET-based applications can bind to COM classes in an early or late bound fashion. Early binding requires complete type information for the COM class at compile-time and requires the underlying COM class to support early binding as well. COM type definitions usually reside in a type library. To use COM types in managed code, you must generate metadata from type libraries.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.