Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

[OT] Side-by-side assemblies: The nitty-gritty.

by BrowserUk (Patriarch)
on Sep 15, 2012 at 07:46 UTC ( [id://993848]=perlmeditation: print w/replies, xml ) Need Help??

A worked example of using manifests to create side-by-side assembles to allow a single process to use two disparate versions of the same DLL.

Main application executable::

  1. MyApp.c:
    #include <windows.h> #include <stdio.h> typedef void (WINAPI *BOOT)(void); void __declspec(dllimport) doIt( void ); int main( int argc, char **argv ) { char line[1024]; HMODULE ext; BOOT boot; doIt(); if( !( ext = LoadLibrary( argv[1] ) ) ) { printf( "Failed to load library %s: error: %d\n", argv[1], GetLastError() ); exit( -1 ); } if( !( boot = (BOOT)GetProcAddress( ext, "boot" ) ) ) { printf( "Failed to get proc address for boot; error: % +d\n", GetLastError() ); exit( -2 ); } boot(); gets( line ); return 0; }

    MyApp.exe.manifest:

    <?xml version='1.0' encoding='UTF-8' standalone='yes'?> <assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1. +0'> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> <security> <requestedPrivileges> <requestedExecutionLevel level='asInvoker' uiAccess='false' /> </requestedPrivileges> </security> </trustInfo> </assembly>
  2. MyDll.c::
    #include <stdio.h> int __declspec(dllimport) depFunc( int, double ); void __declspec(dllexport) doIt( void ) { printf( "MyDLL: depFunc return %d\n", depFunc( 42, 3.141592653 ) ); return; }

    Mydll.dll.manifest:

    <?xml version='1.0' encoding='UTF-8' standalone='yes'?> <assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1. +0'> <assemblyIdentity type="win32" name="MyDll" version="1.0.0.0" proces +sorArchitecture="amd64"/> <file name="MyDll.dll" /> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Dep" version="2.0.0.0" proc +essorArchitecture="amd64"/> </dependentAssembly> </dependency> </assembly>
  3. Dep.c:
    #include <stdio.h> int __declspec(dllexport) depFunc( int a, double b ) { printf( "depFunc: called with %d, %f\n", a, b ); return 1; }

    Dep.dll.manifest:

    <?xml version='1.0' encoding='UTF-8' standalone='yes'?> <assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1. +0'> <assemblyIdentity type="win32" name="Dep" version="2.0.0.0" processo +rArchitecture="amd64"/> <file name="Dep.dll" /> </assembly>

Extension dll:

  1. Ext\ExtDll.c:
    #include <stdio.h> int __declspec(dllimport) depFunc( int, int ); void __declspec(dllexport) boot() { printf( "ExtDll: depFunc returned: %d\n ", depFunc( 12345, 98765 ) ); return; }

    Ext\ExtDll.manifest:

    <?xml version='1.0' encoding='UTF-8' standalone='yes'?> <assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1. +0'> <assemblyIdentity type="win32" name="ExtDll" version="1.0.0.0" /> <file name="ExtDll.dll" /> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Dep" version="1.0.0.0" proc +essorArchitecture="amd64"/> </dependentAssembly> </dependency> </assembly>
  2. Ext\Dep.c:
    #include <stdio.h> int __declspec(dllexport) depFunc( int a, int b ) { printf( "depFunc: called with %d, %d\n", a, b ); return 1; }

    ext\Dep.dll.manifest:

    <?xml version='1.0' encoding='UTF-8' standalone='yes'?> <assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1. +0'> <assemblyIdentity type="win32" name="Dep" version="1.0.0.0" processo +rArchitecture="amd64"/> <file name="Dep.dll" /> </assembly>

Build:

C:\test\myApp\Ext>cl /nologo /LD Dep.c Dep.c Creating library Dep.lib and object Dep.exp C:\test\myApp\Ext>mt /nologo -manifest Dep.dll.manifest -outputresourc +e:Dep.dll;2 C:\test\myApp\Ext>cl /nologo /LD ExtDll.c Dep.lib ExtDll.c Creating library ExtDll.lib and object ExtDll.exp C:\test\myApp\Ext>mt /nologo -manifest ExtDll.dll.manifest -outputreso +urce:ExtDll.dll;2 C:\test\myApp\Ext>cd .. C:\test\myApp>cl /nologo /LD Dep.c Dep.c Creating library Dep.lib and object Dep.exp C:\test\myApp>mt /nologo -manifest Dep.dll.manifest -outputresource:De +p.dll;2 C:\test\myApp>cl /nologo /LD myDll.c Dep.lib myDll.c Creating library myDll.lib and object myDll.exp C:\test\myApp>mt /nologo -manifest MyDll.dll.manifest -outputresource: +MyDll.dll;2 C:\test\myApp>cl /nologo myApp.c MyDll.lib myApp.c C:\test\myApp>mt /nologo -manifest MyApp.exe.manifest -outputresource: +MyApp.Exe;1

And a run:

C:\test\myApp>MyApp.Exe Ext\ExtDll.dll depFunc: called with 42, 3.141593 MyDLL: depFunc return 1 depFunc: called with 12345, 98765 ExtDll: depFunc returned: 1

And there you have it. One executable using two different versions of the same (named) dll without conflict.


With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

RIP Neil Armstrong

Replies are listed 'Best First'.
Re: [OT] Side-by-side assemblies: The nitty-gritty.
by Anonymous Monk on Sep 16, 2012 at 15:24 UTC
    Ahh, how much easier Unix/Linux make it to be able to do such a simple thing.

      Demonstrate!


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

      RIP Neil Armstrong

      I was pretty sure that this was just another unfounded *nixy brag.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

      RIP Neil Armstrong

Re: [OT] Side-by-side assemblies: The nitty-gritty.
by sundialsvc4 (Abbot) on Sep 18, 2012 at 19:17 UTC

    Hmm... that’s no “boast” ... just a well-known aspect of the system.

    The version-name is part of the file-name and a cache directory is built (in various ways) to allow either a short or a very-specific library name to be requested.   Multiple versions of everything are usually available all the time, so that old software can use old libraries or newer ones as you direct.   The idea of multiple platforms and of targets different from the one you’re on are also considered.   It really is a very different approach.   Which is neither here nor there with regard to your thread.

      Hmm... that’s no “boast” ... just a well-known aspect of the system

      Sorry, but you obviously don't understand the technicalities of the example.

      When you've reproduced the example I gave come back and post it.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

      RIP Neil Armstrong

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://993848]
Approved by Eliya
Front-paged by ww
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (4)
As of 2024-03-28 21:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found