Using a 64-bit DLL

Hi!

This could also be an Enterprise topic, I suppose, but seemed slightly more apropos here.

I’m attempting to use a 64-bit DLL, unfortunately the only pre-built binary provided (and it looks like a total hassle to dig up all the 32-bit parts and recompile them, to say nothing of maintenance after the fact).

Now, I offered to help write up this particular library’s Lua binding, so it looks like I can just build that as a DLL, hook up it to an equally 64-bit Lua, and run them together in a 64-bit process. (I’ve got the DLL parts underway. The binding will take some time, though.) My idea, piggybacking on that, is to write a plugin that launches that process, then uses some form of IPC to send Lua code strings across to it and also to retrieve results back. My hope is to have a process simple enough that I can hook into the parent’s WindowProc and field WM_COPYDATA messages on the receiving end, or maybe even the clipboard if I can get away with it. (After that, the options seem to get more and more onerous.)

Has anybody done anything along these lines? If so, does anything stand out as wrong, or might I be missing a more straightforward way? Can this be done without making the antivirus program cry?  :) (Thinking longer term, could this ever pass muster as a store plugin?)

Many thanks for any suggestions!

The Win32 desktop app that Corona creates is 32-bit.

You *cannot* load 64-bit libraries from a 32-bit app.

So, this is not possible.

You’ll need to use a 32-bit version of this library instead.

Also, the reason that Corona creates a 32-bit app for Windows is because it’ll work on both 32-bit and 64-bit Windows operating systems.  You only have to provide 1 download link… versus a separate 32-bit and 64-bit versions of your app that your customers will have to choose from.

And remember that Microsoft does not support a “universal app” like concept for Win32 classic apps like how it works on OS X.  Microsoft does support universal WinRT apps, but those only work on Windows 8.1 and newer OSes, and cannot be distributed via 3rd party app stores such as Steam, GOG, etc.

Have a look at the following forum post on how to write your own Win32 native plugin.  If you can find a 32-bit version of this DLL or are willing to code yourself, then this should prove to be a big help.

   https://forums.coronalabs.com/topic/57623-support-for-nativenewtextfield/?p=298499

I ought to have been a little more explicit in that the 64-bit process would entail a second executable, basically as elaborated in this comment (in the context of a similar topic, of course). I’m curious whether anybody has tried something like that.

Anyhow, maybe I’ll give it a spin this weekend.

I have built a plugin following that post… which I’m just sort of sitting on, now.  :huh: (It doesn’t exactly scream “Windows-exclusive”…) I was a bit unclear about the “proper” place for the DLL while in the simulator, though. I stashed it in one of the directories turned up by  package.cpath , but I don’t recall that any of them seemed best.

>> I ought to have been a little more explicit in that the 64-bit process would entail a second executable

Oh, I see.  So your 32-bit Corona app will communicate with a 64-bit app that is using that 64-bit library.  That’s definitely possible.  On Windows, I think the best way to communicate between apps (aka: IPC) is via local named pipes, because firewalls won’t throw a fit about them unlike TCP communications.  I’m curious if you can open a named pipe via Lua’s io.open() API.  I’ve never tried it before.  Would probably be easier to do that part in C/C++.

>> I was a bit unclear about the “proper” place for the DLL while in the simulator

For the Corona Simulator, just copy and paste your plugin DLLs to the following directory on Windows…

   C:\Users\<YourUserName>\AppData\Roaming\Corona Labs\Corona Simulator\Plugins

“On Windows, I think the best way to communicate between apps (aka: IPC) is via local named pipes, because firewalls won’t throw a fit about them unlike TCP communications.”

Great, this is exactly the sort of info I was after. I’m moving pipes back to the head of the class among the options.  :) (Argh, but so many tabs open!)

Thanks on the directory bit, too. I believe that is the one I chose, but couldn’t shake the feeling that I was skipping a step.

Come to think of it, I was making some assumptions about how your pair of apps work.

Local named pipes is great if you do not plan on having multiple pairs of your app.  That is, you want to create a single instance of them.  Or 1 of the apps acts like a server (single instance) but supports multiple client instances.  Especially if that single instance app is invisible/hidden on the desktop

If you plan on having multiple app pairs, then perhaps using stdin/stdout would be better.  This makes sense if 1 app will always launch/create the other app.  You would do this by having the 1st app launch the other 2nd app via the Win32 CreateProcess() function which allows you to set up communications via stdin/stdout.  Now, you can do the same with named pipes by passing a unique pipe name to the 2nd app, but I’m thinking using stdin/stdout in this case might be easier.

Well, the two programs are still very much in utero, so assume away.  :slight_smile:

My own particular use cases are editor-type things, at the moment for generating various sorts of textures. These are computer vision-style operations, involving tons and tons of inter-pixel shenanigans, but the library is meant to let you commandeer the GPU to do big swaths of work simultaneously. The GPU being busy and all, it doesn’t really make sense to allow more than one instance to run the workhorse function at once.

That said, this is the sort of library that answers to the “how do I see if two images look alike?” and “how do I detect the beats in this music?” sort of questions, so it isn’t so far-fetched that a few programs would come of it, and thus be ready and waiting.

I’ve been leaning toward the pipes-with-unique name approach, say by some sort of hash with a salt. Some of this could then be fed via the command line to the new process and do double-duty filtering out spurious launches, from double clicks and what not. I’ll have to investigate further to see about some basic security measures, like guarding against someone swapping in impostor executables. Something along the lines of requiring a checksum, when a “release build” flag is set? Anyhow, I guess it only really matters if and when this stuff gets out into the wild. I still need to let these ideas work themselves out a bit.  :slight_smile:

Okay, the binding itself is quite well along at this point, so I’m starting to turn my attention back in this direction.

In the thread on nativeNewTextField  you mentioned the disparity between getting the active window in a build versus the simulator. Is this still true? Is there a reliable way to handle simulator, or a streamlined approach? You also said that the API is still taking shape, but I wondered if that might be part of it. (Apologies if this has since landed in Enterprise. I don’t think I have enough time to hunt around for it before I need to take off.)

>> In the thread on nativeNewTextField  you mentioned the disparity between getting the active window in a build versus the simulator. Is this still true?

I’m sorry.  I don’t understand the question.

We did add native TextField and TextBox support to Windows in the newest daily builds if that is what you’re asking.  The only limitation is that it doesn’t support the “alpha” and “hasBackground” properties because native Win32 UI doesn’t technically support transparency.

Hi. Sorry, the thread name was just for context. I’m referring to this paragraph:

“There’s just one more thing to note.  We current haven’t made our Win32 specific C APIs public yet since that’s still in flux at the moment.  But we do plan on opening it up in the near future (no specific date yet).  If your plugin needs access to the main window’s HWND and Window messages, and I suspect it does, then a simple solution to this would be to get a hold of the main window’s HWND via Microsoft’s GetActiveWindow() C function.  That’s a safe assumption to make for a Win32 built app (but not a safe assumption in the Corona Simulator).”

Right.  We haven’t exposed Corona’s Win32 platform specific C APIs via Corona Enterprise yet.  Nor do we have an ETA.

But that said, you can use Microsoft’s C APIs to hunt to down the main window’s handle (ie: HWND).  For example, you can call the following function…

   HWND topWindowHandle = GetTopWindow(NULL);

To get a hold of a handle to the top most window in your application.  This will typically be the handle to the main window unless you are display a native alert (aka: MessageBox) or some other window on top via your own C code.  So, if you’re after the root window, then you would call Microsoft’s GetParent() function repeatedly until you reach the root/main window which is parentless.

There is one more thing to note.  Corona renders its OpenGL content to a child control within the main/root window.  That child control is technically a Win32 window as well.  So, if you plan on adding your own child control on top of Corona’s OpenGL content, then you cannot add your control to the main window (ie: the parentless window).  You’ll need to add your control to the child of the parentless window (that child is Corona’s control which we render to).  I hope that makes sense.

Okay, great. I’m basically aiming for a consistent simulator and build experience. I was tending in the direction you described, but hoping for some insights so I don’t just get something working by fluke. :slight_smile:

Since you bring up OpenGL… can I get at the context itself easily? And what is best to link to, in that case? From past release notes I gather that you use glew , so should I hook up to that? Along those same lines, I’ve been meaning to ask forever (but don’t know whom to pester, really) whether there’s any way to spoof a display object to integrate into the display hierarchy, or has been any discussion to that effect. (Obviously this is Here There Be Dragons territory.)

Microsoft’s wglGetCurrentContext() will return the OpenGL context Corona is currently using, but anything you render to it will get blown away by Corona’s rendering system.  You see, your Lua code gets invoked before Corona renders the next frame to OpenGL.  Once your Lua code is done doing its business on that frame, Corona will clear the OpenGL backbuffer and render its next frame of content.  So, I’m not sure what good the OpenGL context will do you.

Now, I do know that Steam’s OpenGL rendered dashboard is able to do this somehow.  They somehow hook into OpenGL and render their dashboard content on top.  I don’t know how they do this though.  It seems like their software knows when we do a SwapBuffer(), because when we don’t (due to no changes being made in the last frame), Steam does not render the next frame within their dashboard.  So, their solution isn’t perfect, but they’ve definitely hooked into the rendering process somehow.  Sorry for not being anymore helpful.

It might be something along these lines? Hooks (There are a few open-source libraries, as well. I found these and those during my initial research on this very topic.) Anyhow, that’s where the “integrate into the display hierarchy” question comes in.  :P By that I meant more along the lines of making your own display object but overriding all the relevant stuff, e.g. bind shader (well, this is probably orthogonal to the object), draw, unbind shader.

That said, these were just ponderings and don’t affect what I’m after in this topic.

The only way for that to work is for Corona’s graphics engine to support native customization.  That something we have to specifically add support for.  Such as custom shaders and texture loading effects…

   https://docs.coronalabs.com/daily/guide/graphics/customEffects.html

   https://docs.coronalabs.com/daily/guide/graphics/textureManagement.html

What Steam is doing is overlaying their graphics on top of an OpenGL scene.  There is no way that they can integrate their graphics within another engine’s scene.

What exactly are you trying to do?

Nothing much, just sounding out ideas.

Okay, I’m somewhere in the middle of writing the pipe server.

I figure I’ll just let the server thread run in a loop, but need to keep Corona informed, of course. Are the event dispatch APIs thread-safe, or am I to account for that on my end? (This is stock Win32 rather than pthreads, though I assume the latter is just a wrapper.)

The general rule that I tell others is if the function is not documented to be thread safe, then assume that’s it not thread safe.  That’s pretty much true of all 3rd party libraries.

You should *never* call into Lua from another thread.  That would definitely cause problems.

The only Corona C APIs that are thread safe are our CoronaLog*() functions.  None of the other Corona C functions are thread safe.

On Windows, an easy way to notify your main thread from another thread is via Microsoft’s “message-only windows”.  These are invisible (ie: no GUI) but can receive Win32 messages.  They’re great for private Windows message communications, avoiding custom WM_USER ID collision with the main window app.  And Microsoft’s PostMessage() API *is* thread safe and is the best and fastest means of notifying your main UI thread.  What you should do is create a “message-only window” on the main UI thread and provide its Win32 handle to your other thread.  Your other thread can then notify your “message-only window” when something has happened.

Huh, I didn’t know message-only windows were a thing. Not terribly surprising, of course. Thanks for that.

I’d already broken out the critical sections.  :smiley: I thought message dispatch might accommodate this sort thing, just given the sort of API it is, but certainly didn’t assume so. I can probably simplify my design a bit, given those windows.

Also, a few posts back I mentioned hooks, but those pertain only to the Windows message pump, it seems. What I was thinking of, but misremembering, were “detours”, though somewhat confusingly they are given the hook nomenclature in this implementation (this one too, linked in its most recent comment), where I first found them.

The Win32 desktop app that Corona creates is 32-bit.

You *cannot* load 64-bit libraries from a 32-bit app.

So, this is not possible.

You’ll need to use a 32-bit version of this library instead.

Also, the reason that Corona creates a 32-bit app for Windows is because it’ll work on both 32-bit and 64-bit Windows operating systems.  You only have to provide 1 download link… versus a separate 32-bit and 64-bit versions of your app that your customers will have to choose from.

And remember that Microsoft does not support a “universal app” like concept for Win32 classic apps like how it works on OS X.  Microsoft does support universal WinRT apps, but those only work on Windows 8.1 and newer OSes, and cannot be distributed via 3rd party app stores such as Steam, GOG, etc.

Have a look at the following forum post on how to write your own Win32 native plugin.  If you can find a 32-bit version of this DLL or are willing to code yourself, then this should prove to be a big help.

   https://forums.coronalabs.com/topic/57623-support-for-nativenewtextfield/?p=298499