问题
Follow up to PInvoke byte array to char not behaving properly in 64 bit. (Stale question and my suspicions were wrong, thus the title and descriptionwas unfitting).
I am using P/Invoke to call C++ code from C#. I have both the C# and C++ projects set to build in x64 in the build configurations of VS. when I run this program, the parameters of the P/Invoke call are shifted by 32 bits as follows
C# : |Parameter 1|Parameter 2|Parameter 3|Parameter 4|
| | | | |
V V V V V
C++: |Parameter 1|Parameter 2|Parameter 3|Parameter 4|
So if I pass 1,2,3,4 from the C# side, the C++ side receives 2,3,4,garbage.
I have worked around this by passing in an extra int in front of the C# parameters without changing the C++ side. this offsets the parameters by 32 bits and realigns them and the program works perfectly.
Does anyone know what is causing this strange offset and the proper way to correct it?
Here is a simplified example showing my method signatures
C# side:
[DllImport(@"C:\FullPath\CppCode.dll", EntryPoint = "MethodName",
CallingConvention = CallingConvention.Cdecl))]
private static extern bool MethodName(parameters);
C++ side:
extern "C" __declspec(dllexport)
bool CppClass::MethodName(parameters)
I suspect that since the parameters are off by 32 bits, there might be something that isn't really being done in 64 bit properly. Perhaps when calling a method, there is an implicit pointer that is passed before the variables? If that is only a 32 bit pointer on the C# side and the C++ is expecting a 64 bit pointer, that could cause this offset situation, but I'm not sure.
回答1:
MethodName
should not be a class instance method, as the first bytes (4 in x86 world, 8 in x64 world) will be used for the class instance pointer in the unmanaged world.
So, it should be a static method (or a C style method).
来源:https://stackoverflow.com/questions/18984300/p-inovke-parameters-offset-by-32-bits-when-compiled-in-64-bit