32 of 64 bit DLL laai van Net bestuur kode
Vra
Ek het 'n onbeheerde DLL (die scilexer.dll van Scintilla-kode redakteur, wat gebruik word deur Scintilla.Net van CodePlex 'n>) wat gelaai uit 'n bestuurde aansoek via die Scintilla.Net komponent. Die vensters bestuur aansoek loop sonder probleem op beide 32 en 64 bit omgewings, maar ek nodig het om verskillende installasies wat die 64 of die 32 scilexer.dll gebruik te maak.
Is daar 'n manier om beide DLLs in 32 en 64 bit formaat versprei sodat die DLL loader van die NET Framework laai die onbeheerde DLL in die 32 of 64 bit formaat afhangende van sommige .config opsie of 'n "pad naam magie "dinge?
Oplossing
P / roep gebruik LoadLibrary om DLLs laai, en as daar reeds 'n biblioteek gelaai met 'n gegewe naam, sal LoadLibrary dit terugkeer. So as jy beide weergawes van die DLL dieselfde naam kan gee nie, maar sit dit in verskillende dopgehou, kan jy so iets doen net een keer voor jou eerste oproep na 'n funksie van scilexer.dll, sonder om jou eksterne verklarings dupliseer:
string platform = IntPtr.Size == 4 ? "x86" : "x64";
string dll = installDir + @"\lib-" + platform + @"\scilexer.dll";
if (LoadLibrary(dll) == IntPtr.Zero)
throw new IOException("Unable to load " + dll + ".");
Ander wenke
Ongelukkig het ek weet niks van hierdie spesifieke DLL weet. Maar wanneer jy die P doen / Roep jouself, en jy kan gaan met 'n bietjie duplisering, is dit moontlik om 'n gevolmagtigde te skep vir elke platform.
Byvoorbeeld, veronderstel dat jy die volgende interface, wat geïmplementeer moet word deur óf 'n 32 of 64 bit DLL:
public interface ICodec {
int Decode(IntPtr input, IntPtr output, long inputLength);
}
Jy skep die gevolmagtigdes:
public class CodecX86 : ICodec {
private const string dllFileName = @"Codec.x86.dll";
[DllImport(dllFileName)]
static extern int decode(IntPtr input, IntPtr output, long inputLength);
public int Decode(IntPtr input, IntPtr output, long inputLength) {
return decode(input, output, inputLength);
}
}
en
public class CodecX64 : ICodec {
private const string dllFileName = @"Codec.x64.dll";
[DllImport(dllFileName)]
static extern int decode(IntPtr input, IntPtr output, long inputLength);
public int Decode(IntPtr input, IntPtr output, long inputLength) {
return decode(input, output, inputLength);
}
}
En uiteindelik maak 'n fabriek wat die regte een vir jou tel:
public class CodecFactory {
ICodec instance = null;
public ICodec GetCodec() {
if (instance == null) {
if (IntPtr.Size == 4) {
instance = new CodecX86();
} else if (IntPtr.Size == 8) {
instance = new CodecX64();
} else {
throw new NotSupportedException("Unknown platform");
}
}
return instance;
}
}
As die DLLs lui is gelaai die eerste keer dat hulle word opgeroep, hierdie eintlik werk, ten spyte van elke platform net in staat is om die weergawe wat is inheems aan dit te laai. Sien hierdie artikel vir 'n meer gedetailleerde verduideliking.
Die beste wat ek vorendag te kom met die volgende:
- Versprei my aansoek met twee DLLs vernoem 64 of 32
- In die belangrikste opstart kode sluit die volgende in:
File.Delete(Application.StartupPath + @"\scilexer.dll"); { // Check for 64 bit and copy the proper scilexer dll if (IntPtr.Size == 4) { File.Copy(Application.StartupPath + @"\scilexer32.dll", Application.StartupPath + @"\scilexer.dll"); } else { File.Copy(Application.StartupPath + @"\scilexer64.dll", Application.StartupPath + @"\scilexer.dll"); } }
Jy kan die dll sit in system32. Die 32 bit in SysWow64 en die 64 bit in die werklike system32. Vir 32 bit aansoek, wanneer thay toegang system32 hulle getrek het om SysWow64.
Jy kan 'n inskrywing in die register te skep. Die sagteware sleutel het 'n subsleutel met die naam Wow6432Node dat 32 bit aansoek te sien as die sagteware sleutel.
Hier is wat Powershell installeerder doen .
Onbestuurde dlls geïnstalleer kan word in die GAC side-by-kant met hul bestuur eweknieë. Hierdie artikel moet verduidelik hoe dit werk.