【发布时间】:2017-06-20 18:28:21
【问题描述】:
我有一个作为 DLL 文件的 cpp 函数,可以从某个文件路径读取文件,如果成功则返回“0”,如果失败则返回其他数字:
short __stdcall ReadPx(char *filePath, MAP *map, int *num);
这个函数在我的 C# 中定义为:
[DllImport("lib.dll", EntryPoint = "ReadPx", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern System.Int16 ReadPx([MarshalAs(UnmanagedType.LPStr)] string filePath, ref MAP Map, ref Int32 numE);
它在main函数中被调用为:
var pix = new MAP();
int num = 1;
string path = "C:/Users/Visual Studio 2015/Projects/testWrapper2/Map\0";
System.Int16 Output = ReadPx(path, ref pix, ref num);
Console.WriteLine(Output);
该函数运行正常,但给出了无效的文件路径错误。我认为问题可能是在 C# 代码中将“String filePath”定义为 Unicode(每个字符 2 个字节),而 ReadPx 需要一个指向简单 ASCII 字符串的指针。这就是为什么我尝试了如下所示的一些修改,但文件路径错误仍然存在。
[DllImport("lib.dll", EntryPoint = "ReadPx", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern System.Int16 ScReadPixMap(IntPtr filePath, ref PIXMAPENTRY pixMap, ref Int32 numEntries);
IntPtr ptrCString = (IntPtr)Marshal.StringToHGlobalAnsi(path);
System.Int16 output = ReadPx(ptrCString, ref pix, ref num);
Marshal.FreeHGlobal(ptrCString);
感谢您的一些想法和建议。谢谢。
【问题讨论】:
-
调试代码的时候,
filePath这个参数有什么作用? -
您使用了错误的调用约定。如果您有 c++ 接口,则必须使用 CDecl 而不是 StdCall,后者是 Windows 调用约定
-
原版正确传递字符串。还有什么不对劲的。做一些调试。
-
@ThomasFlinkow 在我调试时,
filepath包含完整路径。 -
@fins 它没有显示任何奇怪的字符吗?所以也许这不是编码
标签: c# c++ pointers dll dllimport