64位C风格DLL在VB.NET中unsigned short*的DllImport类型映射问询
unsigned short* to VB.NET for Your C DLL Hey there! Let's break down how to properly map that unsigned short* parameter from your PhiOpticsSDK DLL to VB.NET—you were on the right track with IntPtr, but let's clarify the confusion around "size mismatch" and cover the best options for your specific PHI_ComputePush function.
1. The Easiest (and Most Common) Approach: Use UInt16() Arrays
Given your function deals with rows and cols (sounds like image data!), your ptr_in is almost certainly pointing to a contiguous array of 16-bit unsigned integers. In this case, you don't need to mess with raw pointers at all—VB.NET and the CLR will automatically marshal a UInt16() array to a C-style unsigned short* for you.
Here's the corrected DllImport declaration for PHI_ComputePush:
<DllImport("PhiOpticsSDK.dll", CallingConvention := CallingConvention.Cdecl)> Private Shared Function PHI_ComputePush( ByVal ptr_in As UInt16(), ByVal rows As Long, ByVal cols As Long, ByVal pattern As Long, ByVal timeout_ms As Long, Optional ByVal background_offset As Single = 0.0F ) As IntPtr End Function
Quick notes to align with your existing code:
- I mapped
PHI_64toLongsince it's defined aslong longin your header—this matches the 64-bit integer size correctly.PHI_STATUSstays asIntPtrlike yourPHI_LibraryInitializedeclaration.- Added
CallingConvention.Cdeclbecause most C-style DLLs use this calling convention; omitting it can cause stack corruption bugs.
2. When You Need Manual Memory Control: Use IntPtr
If you have to work with unmanaged memory directly (e.g., receiving a pointer from another DLL function), IntPtr is still valid. The "size mismatch" you noticed is probably mixing up the size of the pointer itself (8 bytes on 64-bit systems) with the size of the data it points to (2 bytes for unsigned short). Those are two different things!
When using IntPtr, you'll need to use the Marshal class to read/write the underlying data. For example:
' Read a single unsigned short from the pointer Dim singleValue As UInt16 = Marshal.ReadUInt16(ptr_in) ' Copy the entire array from unmanaged to managed memory Dim pixelArray As UInt16() = New UInt16(rows * cols - 1) {} Marshal.Copy(ptr_in, pixelArray, 0, pixelArray.Length)
And the corresponding function declaration would be:
<DllImport("PhiOpticsSDK.dll", CallingConvention := CallingConvention.Cdecl)> Private Shared Function PHI_ComputePush( ByVal ptr_in As IntPtr, ByVal rows As Long, ByVal cols As Long, ByVal pattern As Long, ByVal timeout_ms As Long, Optional ByVal background_offset As Single = 0.0F ) As IntPtr End Function
Key Things to Double-Check
- Confirm
PHI_EXP_CONVmatchesCallingConvention.Cdecl—if your DLL usesstdcallinstead, swap that out in theDllImportattribute. - Make sure your
Longmapping forPHI_64is correct (sincelong longis a 64-bit signed integer, VB.NET'sLongmaps perfectly to .NET'sInt64). - The optional
background_offsetparameter is properly marked withOptionalin VB.NET to match the C++ default value.
内容的提问来源于stack exchange,提问作者Mikhail

