NLua / NLua

Bridge between Lua and the .NET.

Home Page:http://nlua.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Issue Targeting x86 Platform

hatboyzero opened this issue · comments

nuget.package/tools/net45/GetLibLuaPostBuildCmd.ps1

This file adds post build events that copy the wrong version of the native library for our project. We are developing on an x64 machine, but targeting x86 processors. Because the machine is x64, the install script assumes, incorrectly, that we desire the x64 library, and we get a Bad Image Format exception when we try to run the code.

Also, the path of the reference in the post-build event is hard coded to the development machine, which will result in a failure on our build server.

Maybe this is the same culprit as what is described in #66.

@hatboyzero Have you tried the latest NuGet pakage?

The patch sent by @davidkennedy85 should fix the issue ce7fea3

Can you try the latest NuGet Package? https://www.nuget.org/packages/NLua/1.3.0.2

Thank you.

Actually that's exactly what the script is supposed to do. It looks at the arch. of the machine you're developing on and copies the version of the DLL that is compatible with your machine.

AKAIK NLua is only compatible with x64 projects, which is why I opened issue #66.

That's all fine and good, but what happens when you are developing on one platform but targeting an entirely different one. I know that is not typically the case, but it does happen in real world scenarios. Simply looking at the architecture of the development machine and selecting the appropriate binary for the desired target platform only works if your development platform and target platform are the same, thus excluding my particular use case...

Agree with @hatboyzero you need to look at the currently selected project build configuration and decide based on that, if it is Debug|x86 or Release|x86, picking the x64 native library simply will not work, regardless of the physical architecture of the CPU.

@hatboyzero also mentioned a valid point about hardcoding the path to the binary as full path in a post-build event. This simply wont work on a build server. At a minimum the path must be relative to the project structure. Even better would be to add the (appropriate) DLL as a project member, set the build type to "Content" set it up to "Copy if newer" or "Copy always", this will get it into the bin dir at run time and allow Visual Studio's project system to keep track of the file's location.

I think this issue should be merged with issue #66 as it is the same problem I am having.

What is your configuration (Windows+VS+target project) ?

On Wed, Jan 22, 2014 at 11:33 PM, dcarlson-plazsoft <
notifications@github.com> wrote:

I am having the same issue (BadImageFormatException upon creation of Lua
object). NLua does not work at all on my system. I also got the latest
NuGet package - 1.3.0.2


Reply to this email directly or view it on GitHubhttps://github.com//issues/67#issuecomment-33089091
.

The workstation where this problem was occurring is windows 7 x64, vs2010 pro. I tried both x86 and x64 projects, trying multiple .net versions as well. I installed the vs 2012 c++ redistributable. (http://www.microsoft.com/en-us/download/details.aspx?id=30679) I also tried the latest NuGet package - 1.3.0.2.

However, after getting home, I tried on my laptop and finally got it to work for x64/.net 4.0 and then x86/.net 3.5. So it is possible I just missed something at work yesterday. (My laptop is also windows 7 x64, vs2010 pro)
Now I will have to see if I can get it in our XNA project.

I got it to work on my workstation in a blank x86 Console application, and even a blank XNA application, but not the project with the game in it. It just gives me the exception below every time for that project.
System.BadImageFormatException was unhandled
Message=An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
Source=KeraLua
StackTrace:
at KeraLua.NativeMethods.LuaLNewState()
at KeraLua.Lua.LuaLNewState() in y:\projects\nlua\NLua\Core\KeraLua\src\KeraLua\Lua.cs:line 34
at NLua.LuaLib.LuaLNewState()
at NLua.Lua..ctor()
at YargisNew.YargisGame.DoLuaTest() in C:\Users\dcarlson\Documents\Visual Studio 2010\Projects\Yargis\Yargis\Yargis\Core\Game.cs:line 296
at YargisNew.YargisGame..ctor() in C:\Users\dcarlson\Documents\Visual Studio 2010\Projects\Yargis\Yargis\Yargis\Core\Game.cs:line 91
at YargisNew.Program.Main(String[] args) in C:\Users\dcarlson\Documents\Visual Studio 2010\Projects\Yargis\Yargis\Yargis\Core\Program.cs:line 13
InnerException:

EDIT: It turns out there was a post build script doing something to the dlls. After deleting that and recopying, it worked.
Thank you.

This problem still appears to occur with the latest (1.3.0.2) NuGet package.

Steps to reproduce:

  1. Create an empty Console Application project in Visual Studio 2013 for .NET Framework 4.5 (on a 64-bit platform)
  2. Add the NLua package to the project using NuGet
  3. Write some code to use NLua in the console app's Main method.
  4. Run

This is the resulting exception:

An unhandled exception of type 'System.BadImageFormatException' occurred in KeraLua.dll

Additional information: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)

Stack Trace:
   at KeraLua.NativeMethods.LuaLNewState()
   at KeraLua.Lua.LuaLNewState()
   at NLua.LuaLib.LuaLNewState()
   at NLua.Lua..ctor()
   at ConsoleApplication2.Program.Main(String[] args) in c:\Users\dion.williams.COLLABCO\Documents\Visual Studio 2013\Projects\ConsoleApplication2\ConsoleApplication2\Program.cs:line 14
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

It's likely caused because the 64-bit native Lua DLL is placed in the bin folder in a post-build event, even though projects have "Prefer 32-bit" set by default and target the "Any CPU" platform.

There are a few problems in place with the current nuget package. All from the same cause. Essentially when the package is installed it adds a post build event like this:

xcopy /s /y "c:\users\username\Source\Repos\helios\packages\NLua.1.3.0.2\lib\native\x64\*.*" "$(TargetDir)"

There are multiple problems with this build event, all stemming from the fact that they are hardcoded to the first machine that processes the nuget install script. First fix would be to not hardcode the path to the packages directory. It would then look like this.

 xcopy /s /y "$(SolutionDir)packages\NLua.1.3.0.2\lib\native\x64\*.*" "$(TargetDir)"

Now if you check out the source on a second machine and compile it. It will still work. Now we hit the second problem which is that the platform architecture is hardcoded into the xcopy as well. What is worse is that it was driven by querying the build machine architecture instead of the build target. This is partially fixed by using another variable in the post build event as follows:

xcopy /s /y "$(SolutionDir)packages\NLua.1.3.0.2\lib\native\$(PlatformName)\*.*" "$(TargetDir)"

Now we have the last problem which in all honesty is not resolvable. That is the fact that we are adding dependency with native unmanaged code. This causes significant problems with an AnyCPU target, and probably should not be supported. AnyCPU has many possibilities on run time environment... x86, x64 and arm. To support them NLua will have to dynamically import the right library at run time instead of just copying the dependencies with the appropriate name to the right place.

Lastly not related to the post build xcopy is the project references. The nuget package added the x86 dll as the reference but was copying the 64bit. I'm not sure how it decided which references to add.

The easiest way to "decide" which native library to add is to let the developer do it.

The easiest way to let the developer decide is to create a version of the package for each platform (x86 and x64, and no package for "Any"). A developer should know what platform they are targeting, and choose the appropriate package, and each package should include only one version of the native library.

My suggestion for "deploying" the native library is to add it to the "content" folder and and include a install.ps1 to set the copy property to "Copy Always."

Here is a gist for the install.ps1 file: https://gist.github.com/jamesrcounts/10690582

Fixed. Just create a folder x86 and x64 and copy each version of native lua52.dll (grab from the the README.md since the NuGet is not updated).

Thanks @viniciusjarina - is the nuget package going to be updated in the near future?

Please update the Nuget package. Thank you.

I am doing this..I am trying to finish the Windows Store version first ;)

On Thu, Oct 2, 2014 at 10:17 AM, zunath notifications@github.com wrote:

Please update the Nuget package. Thank you.


Reply to this email directly or view it on GitHub
#67 (comment).

Is there any progress on updating the NuGet Package? I'd really like to add a dependency to NLua from my DynamicLua instead of including it, but this would require a version that has this bug fix included ;)

@nrother This was fixed a long time ago.

Is not working for you?

Eight years later... I downloaded the most recent NuGet packages (1.6.3) which includes the KeraLua dependency (1.3.4). I built a test application and it ran perfectly the first time, but on the second and subsequent attempts I got the System.BadImageFormatException exception described earlier in this issue. I am running a Windows Forms application on .NET 4..8 framework and targeting AnyCPU.

My fix was to uncheck the "Prefer 32-bit" option in the Compile properties of my Windows Forms project. With that off, it works reliably.

I am currently only building on a dev machine so this may come back to bite me at release time, but as of today that was my fix.