0

Backstory: I'm working on bridging a 64 bit process to a 32 bit DLL using a COM object.

Why? Good question. It's not currently feasible to recompile all the x86 source to x64, unless there's absolutely no way around it...enter IPC.

I know it's not going to perform as well; making it work is my current task...I assume once it's seen that it doesn't perform as well, I'm going to be told to recompile all the x86 source anyway.

What's cool, though, is that it works with the testbed I've built. I'm having problems bringing it up to scale, however.

I am very unfamiliar with COM -- in fact the beginning of this week, Apr. 16, 2018 is literally the first time I've ever done anything with it.

I've got three pieces: the x64 exe, the x86 -> x64 surrogate exe, and an x86 .dll

the x64 exe seems to work fine:

CoInitialize(NULL);

CLSID clsid;
Ix86LibraryProxy* pProxy;

HRESULT hr = CLSIDFromProgID(OLESTR("x86x64.x86LibraryProxy"), &clsid);
hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_Ix86LibraryProxy, (void **) &pProxy);
hr = pProxy->Load(HandleToLong(FindWindow(szWindowClass, szTitle)));
CoUninitialize();

This is the x86 -> x64 surrogate exe

// header file declaration
STDMETHOD(Update)(const float& dt, HRESULT* hResult);

//cpp file
STDMETHODIMP Cx86LibraryProxy::Update(const float& dt, HRESULT* hResult)
{
    typedef HRESULT(*DLL_Update)(const float& dt);

    *hResult = S_OK;
    HMODULE hLib = LoadLibrary(L"DLL.dll");

    if (hLib != NULL)
    {
        DLL_Update pFunc = (DLL_Update) GetProcAddress(hLib, "Update");
        if (pFunc != NULL)
        {
            *hResult = (*pFunc)(dt);
        }
        else
        {
            *hResult = E_FAIL;
        }
    }
    else
    {
        *hResult = E_INVALIDARG;
    }

    FreeLibrary(hLib);
    return S_OK;
}

This is an export from the x86 dll

//x86 dll export
__declspec(dllexport) HRESULT Update(const float& dt)

Pretty standard runtime application stuff. The .dll has a function in it that takes in a const float& dt and returns an HRESULT.

Obviously at scale I wouldn't unload & reload the DLL every time I call this function.

In my .idl file I have the following:

interface Ix86LibraryProxy : IDispatch{
    [id(1)] HRESULT Load([in] LONG hWnd, [out, retval] HRESULT* hResult);
    [id(2)] HRESULT Update([in] const float& dt, [out, retval] HRESULT* hResult);
    [id(3)] HRESULT Render([out, retval] HRESULT* hResult);
};

with compiler error Error 1 error MIDL2025: syntax error : expecting a declarator or * near "&"

I've see that MIDL doesn't support c++ constructs, but what I don't see is a way around it.

Any changes to the signature in the .idl file ([id(2)] HRESULT Update([in] const float dt, [out, retval] HRESULT* hResult);) generates this error: Error 1 error C2259: 'ATL::CComObject<T>' : cannot instantiate abstract class

I see this question asks a similar one, but the answer to it doesn't feel like it answers the question, since it doesn't do anything with the MIDL file: https://stackoverflow.com/a/3028861/4518677

Since it doesn't appear that MIDL supports passing by reference, what would be a way around this?

What I also don't understand is that if the project for the x86 dll isn't under the same solution as the x86 -> x64 surrogate process, the x86 -> x64 surrogate process can't find the module when it tries to LoadLibrary("DLL.dll") with GetLastError() == 126

P-Squiddy
  • 65
  • 1
  • 13
  • float& is C++ syntax, MIDL syntax is C based. So it needs to be float*. Notable is that you did not get far enough to discover that GetProcAddress() cannot work, COM interface functions are not exported. – Hans Passant Apr 19 '18 at 15:48
  • @HansPassant It works no problem because the x86 dll is not a COM one. The x86 -> x64 Surrogate Process is the COM process...as I mentioned, it's working save the float&. – P-Squiddy Apr 19 '18 at 17:05
  • Since it's an `in` parameter, the COM object could just take it by value: `[in] float dt`. It's not clear why the DLL takes it by reference in the first place. – Igor Tandetnik Apr 19 '18 at 18:04
  • *"Any changes to the signature in the .idl file ... generates this error"* Of course. Once you've updated the signature in the interface, you need to update the implementation to match. – Igor Tandetnik Apr 19 '18 at 18:05

0 Answers0