How to cast FARPROC! to Func<SomethingElse>?

windows
silver

#1

I’m trying to load a DLL with LoadLibrary, get an export using GetProcAddress and call it.

(This is basicaly the same problem as in Calling functions exported by Dlls from Silver)

The code looks something like:

var hSilverDLL1 = LoadLibrary("SilverDLL1.dll")
var pFoo = GetProcAddress(hSilverDLL1, "_Foo@0");
var pFoo2 = pFoo as Func<Bool>

This fails with:

error E559: Cannot safely cast "FARPROC!" to "Func<Bool>" did you mean to use "as!"?
error E129: Cannot cast from "FARPROC!" to "Func<Bool>!"

Using as! doesn’t help. The first error disappears but the second remains. Trying to pass through LPVOID like this:

var pFoo = GetProcAddress(hSilverDLL1, "_Foo@0");
var pFoo2 = pFoo as! rtl.LPVOID
var pFoo3 = pFoo2 as! Func<Bool>

doesn’t work either:

error E129: Cannot cast from "LPVOID!" to "Func<Bool>!"

(Using as rather than as! gives even more errors. like in the first excerpt.)

The suggestion is the post I linked above doesn’t work for me. I can’t statically linked to the DLL. I need to load it at runtime and discover its exports at runtime.

Am I missing some obvious way to perform this cast?

(Using Elements 10.0.0.2255 on VS 2015 on Windows 10 x64, compiling x86 binaries.)


Access Violation casting FARPROC to Any in Silver
Access Violation casting FARPROC to Any in Silver
(Carlo Kok) #2

See


(marc hoffman) #3

https://docs.elementscompiler.com/API/Aspects/FunctionPointer/ doesn’t work in Swift/Island?


(Carlo Kok) #4

That works too.


#5

Maybe I’m doing something wrong but I can’t get it to compile.

I’m doing something like (shamelessly adapted from the GUI sample):

import rtl

class Program {
    @FunctionPointer private typealias FooType = () -> (Bool)

    static let szTitle: LPCWSTR = "RemObjects Elements — Island Windows Sample"
    static let szWindowClass: LPCWSTR = "IslandWindowsSample"
    static var button: HWND = nil

    @CallingConvention(CallingConvention.Stdcall)
    static func WndProc(_ hWnd: HWND, _ message: UINT, _ wParam: WPARAM, _ lParam: LPARAM) -> Integer {
        switch message {
            case WM_COMMAND:
                if wParam == BN_CLICKED && lParam == button as! rtl.LPARAM {
                    MessageBox(hWnd, "You clicked, hello there!", szTitle, 0)
                    var x = true

                    var hSilverDLL1 = LoadLibrary("SilverDLL1.dll")
                    var pFoo = GetProcAddress(hSilverDLL1, "_Foo@0")
                    
                    var pFoo3 = pFoo as? FooType
                    x = pFoo3()

                    if (!x) { writeLn("fdg") }
                }
.....

I still get: (E129) Cannot cast from "FARPROC!" to "Program.FooType?"


(Carlo Kok) #6

You need the upcoming beta (fridays) build.


#7

Thanks. I’ll try it out as soon as it gets to the public stable channel.

Will I be needing both @FunctionPointer mentioned here and @convention(c) mentioned in the other post or will only one of them be enough?
Strike that. I see that in the other post you wrote that @convention alone should be enough.