DllNotFoundException while trying to "fix" LuaInterface, but why? - c#

Since my game, which I'd really like to be Mono-usable, does not seem to run under Linux because LuaInterface is being a jerk (see the the relevant SO thread for more on that), I've decided to do what's suggested there. I wrote my own Lua511.LuaDLL class to reflect the one used by LuaInterface, replacing every single public function with its respective DllImport from lua51:
//For example, like this:
[DllImport("lua51")]
public static extern IntPtr luaL_newstate();
With the edited LuaInterface.dll (which now hosts its own Lua511.LuaDLL) and a pure, native Win32 lua51.dll in my game's startup folder, I somehow get a DllNotFoundException when LuaInterface tries initialize:
public Lua()
{
luaState = LuaDLL.luaL_newstate(); //right there, right then.
...
Ofcourse, with the DLL right there it shouldn't do that, right? Strangely, putting back the messed-up .Net version of lua51.dll gives an EntryPointNotFoundException instead. The mind boggles.
So what's up with that?
Relevant source code: Lua511.cs, dropped it in the LuaInterface project, then removed the reference so it'd be replaced.
Edit: Screw this, I'm gonna look for alternatives. Or roll my own. Or just stop caring about Linux compatibility.

You referenced my question. I took the other way to solve the problem and started to develop a new Lua .NET interface. I called it Lua4Net.
You can find the sources on Google hosting. And here the unit tests.
Currently implemented features: Execute code with exception handling and provide the return values; register global functions with parameter handling.
Features that will follow: Get/set global variables; debugging support, ...
You can find the used native windows DLL here (it is the renamed VC++ 9.0 DLL from here).
AND: Today I ran my first Linux/Mono tests, and all my unit tests worked!!!

AFAIK mono uses .so extension for native libraries under Linux by default.
Try to rename your lua51.dll to lua51.so or change dllname in DllImport attribute. Or use dllmap.

Related

Is it possible to have the program entry point in a library assembly?

In compiled system languages (like C/C++), generally, the entry point is resolved at link time, which gives the ability to have the main function in a DLL so the linker won't complain and set the entry point address to the symbol in the DLL (or the function in the import library, not sure about that).
I recently started using C# and I would like to do something similar, where I have the Main method in a library (which preferably build against .NET Standard) and the actual exe don't define any entry point and uses the one in the library.
I get that I could just write a Main method in the exe and call the Main of the library in it, but the point is that I would like to avoid that.
I believe Winforms and WPF provide something similar, so hopefully what I'm trying to do is possible, otherwise, please educate me on the reasons why .NET doesn't provide such mechanism.
There seems to be a misunderstanding here:
In .NET, the only difference between a DLL and an EXE is purely the presence of .entrypoint in the header, which identifies the starting method that the CLR bootstrapper calls.
If there isn't one then it's a library rather than an application. It makes no sense to have an EXE which has no .entrypoint on any method, it won't run because the CLR bootstrapper won't know what to do with it.
Winforms and WPF do not do what you claim: they have a normal .entrypoint, it just happens to be boiler plate code which you don't need to worry about.
For clarity: the actual extension of the file is somewhat irrelevant. It's perfectly legal to call an assembly whatever you want, and you can link an assembly containing .entrypoint within another one, whether or not it has .exe extension or any other.
However, Windows will only bootstrap a file automatically if it has the .exe extension, as the CLR bootstrapper itself needs bootstrapping. You can though call AppDomain.ExecuteAssembly which essentially does the same thing from within another app.

How are APIs or Frameworks made, so scripts can use their functions but you cannot see the code?

I was wondering how I could program like a certain API, I have written an algorithm that I want to publish so people can use it, but I don't want people to see the code, and steal it? Paranoid, I know, but still.
How is that made, so for instance I can in a C# script (the API would also be written in C#), include it (with using ApiName) and use the functions inside, for instance if the API has a function that I program like "void Calculate(float x, float y)", and then from a script they can call "Calculate(100, 200)" for instance. I know it's somehow possible because of the Windows API, etc. Also is creating a Class Library the same thing?
Before any code runs, it is either compiled or interpreted into binary. This is highly simplified but that is the general idea. As long as a library or API provides an interface like names of functions, the implementation itself can be compiled and still work.
For C#, NuGet is a good example, you can create a NuGet of your code (see https://learn.microsoft.com/en-us/nuget/create-packages/creating-a-package) where the public function and method signatures will be visible and usable but the implementations will be compiled. DLLs work in a similar way. You can reference them and call their public members but not see the code unless you use a tool to decompile them.

How to handle dll dependency that may not be present? [duplicate]

I am not sure the best way to explain this so please leave comments if you do not understand.
Basically, I have a few libraries for various tasks to work with different programs - notification is just one example.
Now, I am building a new program, and I want it to be as lightweight as possible. Whilst I would like to include my notification engine, I do not think many people would actually use its functionality, so, I would rather not include it by default - just as an optional download.
How would I program this?
With unmanaged Dlls and P/Invoke, I can basically wrap the whole lot in a try/catch loop, but I am not sure about the managed version.
So far, the best way I can think of is to check if the DLL file exists upon startup then set a field bool or similar, and every time I would like a notification to be fired, I could do an if/check the bool and fire...
I have seen from the debug window that DLL files are only loaded as they are needed. The program would obviously compile as all components will be visible to the project, but would it run on the end users machine without the DLL?
More importantly, is there a better way of doing this?
I would ideally like to have nothing about notifications in my application and somehow have it so that if the DLL file is downloaded, it adds this functionality externally. It really is not the end of the world to have a few extra bytes calling notification("blabla"); (or similar), but I am thinking a lot further down the line when I have much bigger intentions and just want to know best practices for this sort of thing.
I do not think many people would
actually use its functionality, so, I
would rather not include it by default
- just as an optional download.
Such things are typically described as plugins (or add-ons, or extensions).
Since .NET 4, the standard way to do that is with the Managed Exensibility Framework. It is included in the framework as the System.ComponentModel.Composition assembly and namespace. To get started, it is best to read the MSDN article and the MEF programming guide.
You can use System.Reflection.Assembly and its LoadFile method to dynamically load a DLL. You can then use the methods in Assembly to get Classes, types etc. embedded in the DLL and call them.
If you just check if the .dll exists or load every .dll in a plugin directory you can get what you want.
To your question if the program will run on the user's machine without the dlls already being present - yes , the program would run. As long as you dont do something that needs the runtime to load the classes defined in the dll , it does not matter if the dll is missing from the machine. To the aspect you are looking for regarding loading the dll on demand , I think you are well of using some sort of a configuration and Reflection ( either directly or by some IoC strategy. )
Try to load the plugin at startup.
Instead of checking a boolean all over the place, you can create a delegate field for the notification and initialize it to a no-op function. If loading the plugin succeeds, assign the delegate to the plugin implementation. Then everywhere the event occurs can just call the delegate, without worrying about the fact that the plugin might or might not be available.

Problems when trying to use ksp/unity3d binaries?

I'm trying to use the kerbal space program (ksp) binaries to read in one of the ksp part models, I've added the ksp binaries and UnityEngine.dll under references then I'm doing the following:
Planet p = new Planet();
Running this gives me the following security exception:
ECall methods must be packaged into a system module.
Can I bypass or fix this?
Edit:
I found out that it's not from the ksp dll but from untiy ones, they use:
[WrapperlessIcall ]
[MethodImpl (MethodImplOptions.InternalCall)]
public extern void StopAllCoroutines ();
I need a way to get past this.
MethodImplOptions.InternalCall merely indicates that StopAllCoroutines is implemented directly in the CLR rather than the BCL (or some other library). Here's MSDN.
As to revising Unity3D not call in to this, you won't be able to bypass it.

How to add a reference to a library

I have found a math parser Here. I have never added something like this to a program and was wondering what I need to do to add thing like this to a program. For example I want to know where to put the file and how to call it in the headers so that I can use the classes inside the file. I looking for general instructions that can be applied to other things as well.
Sounds like you have come from a bit of a C background. C# is a little different in the way that we pull in external code, and its actually quite a bit easier than C.
To reference some code using Visual Studio, you will need to add a reference to that dll. once you have the dll included (via a reference) in your project you can use it in your code by adding a using statement and then instantiating objects from that library
MSDN docs around this are here: http://msdn.microsoft.com/en-us/library/wkze6zky.aspx
EDIT:
if you are outside of VS as you have specified there's a few things you will need to do:
Let your compiler know where the assembly is so that it can correctly link
Add the assembly to your running directory (it should sit alongside your executable)
OR add your library to the GAC
OR manually load it with an Assembly.Load call

Categories

Resources