Jump to content

64bit KSP - External library question


MeateaW

Recommended Posts

Hi All,

I am fixing up a mod (for personal use - license doesn't let me distribute derivatives - but will contact the author if I get it going).

That mod imports some functions from a DLL, obviously it was a 32bit DLL in the past.

Is there any way within the KSP API to detect if you are running 64 or 32bit?

I obviously need to have some code that detects which mode I am in, and load the DLL that is appropriate.

Thanks!

PS.

I am a developer by trade, but have very little KSP modding experience (so don't know where to start to look for API documentation).

(The mod I am refurbing is kerbcom avionics, which was last touched by its dev for ksp ~21.something, things have changed since then! - but yeah wont be releasing anything due to license - I may release diff files to allow the adventurous to compile their own version of my changes if I ever get it working, but tbh I wonder if even that is against the license - need to research first).

Link to comment
Share on other sites

In this instance, the native code DLL was the Linear Programming solving library: "Lpsolve". Used by Kerbal Avionics.

When running KSP 64 bit it failed to load the DLL (the debugger indicated that it "could not find DLL").

Process monitor indicated that it could indeed find the DLL (many "Success" open-file events), however even after finding it it kept looking in other locations.

On a hunch I tried the code on KSP32 bit and it worked fine (all other things were the same).

So, I grabbed a 64 bit version of the DLL off the web, replaced it, and tried it again in 64bit and it worked.

So; there was no obvious "this DLL is the wrong archictecture" message, however by a process of elimination I came to that conclusion. (and with something somewhat related to this code have effectively solved the problem).

Just to explain how I solved it:

(Note: this is not the only method, there are easier methods, and for my particular problem this method resulted in a LOT of extra code! - but it was all automated searches and replaces so wasn't as bad as it sounds).

Lets say you need to import a function from a library:

You would use something like this:


public static class Library
{
[DllImport("dllpath\dllfile.dll", SetLastError=true)]
public static extern bool add_column(int lp, double[] column);
}

And you would call that code like this:


void Function()
{
if (Library.add_column(intvalue, arrayofDouble))
{ /* Cheer! */ }
}

I wanted to ensure that whatever bit-version I needed was loaded, without changing any of my native calls.

So I don't change my calling-code, but I *do* change my library to the following:


public static class Library
{
[DllImport("dllpath\dll_32bit.dll", SetLastError=true)]
public static extern bool add_column_32(int lp, double[] column);

[DllImport("dllpath\dll_64bit.dll", SetLastError=true)]
public static extern bool add_column_64(int lp, double[] column);

public is64bit { get { return IntPtr.Size == 8; } }

public delegate bool add_column_delegate(int lp, double[] column);

public static add_column_delegate add_column { get { return is64bit? (add_column_delegate)add_column_64 : (add_column_delegate)add_column_32; } }
}

I can guarantee this is not the "simplest" way of doing it, but it is certainly *a* way of doing it.

Also; the internet when it saw this problem was similarly confused about why a 64bit application couldn't call a 32bit dll. (In fact most of the internets response was: "Just call the 32bit version"). However for whatever reason this did not work for the default compilation method of the ksp mod.

Note:

My actual code was slightly more complex than this, but only because I had to split it over 3 files.

Eg:


public static class Library
{
private is64bit { get { return IntPtr.Size == 8; } }
public delegate bool add_column_delegate(int lp, double[] column);
public static add_column_delegate add_column { get { return is64bit? (add_column_delegate)Library_64.add_column : (add_column_delegate)Library_32.add_column; } }
}
public static class Library_64
{
private const string DLLPath = "dllpath\dll_64bit.dll";

[DllImport(DLLPath, SetLastError=true)]
public static extern bool add_column(int lp, double[] column);
}

public static class Library_32
{
private const string DLLPath = "dllpath\dll_32bit.dll";

[DllImport(DLLPath, SetLastError=true)]
public static extern bool add_column(int lp, double[] column);
}

The main reason for this, is the difference between the 32 and 64 bit import-classes, is precisely 2 lines.

The class Name, and the Constant-String variable.

Again; no guarantees this is the best way of doing this, just that it is *a* way of doing it.

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...