2

I have been working on wrapping WindowsPortableDevice Api for Golang. The c++ code below was working but suddenly is not working.

libgowpd.h:

#include <Windows.h>

typedef struct IPortableDeviceManager IPortableDeviceManager;

HRESULT createPortableDeviceManager(IPortableDeviceManager **pPortableDeviceManager);

libgowpd.cpp:

#include <libgowpd.h>

HRESULT createPortableDeviceManager(IPortableDeviceManager **pPortableDeviceManager) {
    HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    if (SUCCEEDED(hr)) {
        hr = CoCreateInstance(CLSID_PortableDeviceManager,
            NULL,
            CLSCTX_INPROC_SERVER,
            IID_PPV_ARGS(pPortableDeviceManager));
    }

    return hr;
}

In Golang

/*
#cgo CFLAGS: -blahblah
#cgo LDFLAGS: -llibgowpd -Ole32

include "libgowpd.h"
*/
import "C"

type HRESULT uint64
type IPortableDeviceManager C.IPortableDeviceManager

func CreatePortableDeviceManager() (*IPortableDeviceManager, error) {
    var pPortableDeviceManager *C.struct_IPortableDeviceManager// No matter whether C.IPortableDeviceManager or C.struct_IPortableDeviceManager

    hr := C.createPortableDeviceManager(&pPortableDeviceManager)

    if hr < 0 {
        return nil, HRESULT(hr)
    }
    if pPortableDeviceManager == nil {
        return nil, E_POINTER
    }

    log.Println("CreatePortableDeviceManager(): Create portable device manager instance.")

    return (*IPortableDeviceManager)(pPortableDeviceManager), nil
}

I think I pass pointer to pPortableDeviceManager correctly via getting address of pPortableDeviceManager but it returns 0x80070057 error code(E_INVALIDARG).

What have I done wrong?

  • 2
    You need to read the documentation for [CoInitializeEx](https://msdn.microsoft.com/en-us/library/windows/desktop/ms695279.aspx). The way you are using it is unusual to say the least. And probably wrong. Don't try to initialize COM from your library. Have clients of your library initialize COM on the calling thread. – IInspectable Oct 03 '17 at 10:12
  • I removed init code in cpp and written the code in Golang. (`hr := C.CoInitializeEx(nil, C.COINIT_MULTITHREADED)`) And this code returns S_OK but problem still remains. – RedLaboratory Oct 03 '17 at 10:26
  • Not so easy to see whether the -blahblah compile option takes care of the proper calling convention. HRESULT is a 32-bit type. – Hans Passant Oct 03 '17 at 10:41
  • @HansPassant -blahblah is just include options to find `libgowpd.h` file. And I don't know why but when I try to cast `C.E_SOMEERROR` to `uint32`, go compiler throws overflow error. – RedLaboratory Oct 03 '17 at 10:52
  • `HRESULT`'s are signed 32-bit values. Your code doesn't appear to acknowledge this. – IInspectable Oct 03 '17 at 11:02
  • the `E_INVALIDARG` can be or when *pPortableDeviceManager* == 0 or when *dwClsContext* is invalid. simply look in debugger parameters in call `CoCreateInstance` – RbMm Oct 03 '17 at 13:11
  • @RbMm `IID_PPV_ARGS` macro couldn't get `IID` of pointer. So the problem was `dwClsContext`. I manually set parameter so that I could solve the problem. Thank you all! – RedLaboratory Oct 04 '17 at 08:11

0 Answers0