Как я должен передать нулевой указатель на функцию C ++, как IntPter.Zero в C #? - PullRequest
0 голосов
/ 07 января 2019

Я пытался использовать C ++ dll, используя fii, одну из функций, объявленных так:

QCAP_CREATE( CHAR * pszDevName /*IN*/, UINT iDevNum /*IN*/, HWND hAttachedWindow /*IN*/, PVOID * ppDevice /*OUT*/, BOOL bThumbDraw = FALSE /*IN*/, BOOL bMaintainAspectRatio = FALSE /*IN*/ );

Я попытался передать нулевой указатель на третий параметр "hAttachedWindow" с помощью ref, как это:

const ffi = require('ffi');
const ref = require('ref');
const path = require('path');

let dllPath = path.join(__dirname, '/QCAP.X64');
let intPtr = ref.refType('int');

let QCAP = ffi.Library(dllPath, {
  'QCAP_CREATE': [ref.types.ulong, [ref.types.CString, ref.types.uint, 
  intPtr, intPtr, ref.types.bool, ref.types.bool]]
});

let ppdevice = ref.alloc('int');
let initResult = QCAP.QCAP_CREATE('CY3014 USB', 0, ref.NULL, ppdevice, true, false);

но функция продолжает генерировать ошибку, указав, что третий параметр действителен, я успешно импортировал эту функцию в C # следующим образом,

    [DllImport(@"D:\01work\01code\video\code\VideoDemo\CPlusPlus\obj\Debug\QCAP.X64.DLL", EntryPoint = "QCAP_CREATE")]
    public static extern ulong QCAP_CREATE(string deviceName, UInt32 iDevNum, IntPtr hAttachedWindow, out IntPtr ppDevice, bool bThumbDraw, bool bMaintainAspectRatio);

    static void Main(string[] args)
    {
        try
        {
            public IntPtr ppDevice = new IntPtr(0x00000000);
            var result = QCAP_CREATE("CY3014 USB", 0, IntPtr.Zero, out ppDevice, true, false);
        }

Я проверил исходный код ref, он сказал, что ref.NULL равен

/ ** Буфер, который ссылается на указатель C NULL. * /

так что я думаю, что ref.NULL равно IntPtr.Zero в C #, но это неправильно. Я долго гуглял эту проблему, но ничего не помогло, кто-нибудь может дать мне совет? Большое спасибо!

1 Ответ

0 голосов
/ 07 января 2019

Часть вашей путаницы заключается в том, что тип C # IntPtr представляет не «указатель на int», а «указатель, интерпретируемый как int».

Другая часть заключается в том, что после очистки псевдонимов до соответствующих типов третий и четвертый параметры являются различными типами указателей, void * и void **. Привязка C # скрывает это, поскольку квалификатор out передает адрес выделенного IntPtr, что позволяет функции библиотеки изменять его.

Попробуйте это

const ffi = require('ffi');
const ref = require('ref');
const path = require('path');

let dllPath = path.join(__dirname, '/QCAP.X64');
let voidPtr = ref.refType(ref.types.void);
let voidPtrPtr = ref.refType(voidPtr);

let QCAP = ffi.Library(dllPath, {
  'QCAP_CREATE': [ref.types.ulong, [ref.types.CString, ref.types.uint, 
   voidPtr, voidPtrPtr, ref.types.bool, ref.types.bool]]
});

let ppdevice = ref.alloc(voidPtrPtr);
let initResult = QCAP.QCAP_CREATE('CY3014 USB', 0, ref.NULL, ppdevice, true, false);
let pdevice = ppdevice.deref();
...