首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么我不能在发布版本中将字符*字符串从C++返回给C#?

为什么我不能在发布版本中将字符*字符串从C++返回给C#?
EN

Stack Overflow用户
提问于 2011-06-10 06:33:08
回答 5查看 15.6K关注 0票数 24

我正在尝试从C#调用以下简单的C函数:

代码语言:javascript
复制
SIMPLEDLL_API const char* ReturnString()
{
    return "Returning a static string!";
}

使用下面的P/Invoke声明(有没有return属性,都没有区别):

代码语言:javascript
复制
[DllImport("SimpleDll")]
[return: MarshalAs(UnmanagedType.LPStr)]
public static extern string ReturnString();

如果DLL是调试版本,但在发布版本(AccessViolationException)中崩溃,则此方法有效。

我调用了十几个其他简单的函数,这是唯一失败的函数(下面是其他函数:)

代码语言:javascript
复制
[DllImport("SimpleDll")] public static extern int NextInt();
[DllImport("SimpleDll")] public static extern void SetNextInt(int x);
[DllImport("SimpleDll")] public static extern int AddInts(int a, int b);
[DllImport("SimpleDll")] public static extern int AddFourInts(int a, int b, int c, int d);
[DllImport("SimpleDll")] public static extern double AddDoubles(double x, double y);
[DllImport("SimpleDll")] public static extern IntPtr AddDoublesIndirect(ref double x, ref double y);
[DllImport("SimpleDll")] [return: MarshalAs(UnmanagedType.U1)]
public static extern char CharStringArgument([MarshalAs(UnmanagedType.LPStr)]string s);
[DllImport("SimpleDll")] [return: MarshalAs(UnmanagedType.U2)]
public static extern char WCharStringArgument([MarshalAs(UnmanagedType.LPWStr)]string s);
[DllImport("SimpleDll")] [return: MarshalAs(UnmanagedType.LPWStr)]
public static extern string ReturnWString();
[DllImport("SimpleDll")] [return: MarshalAs(UnmanagedType.BStr)]
public static extern string ReturnBSTR();
[DllImport("SimpleDll")] public static extern System.Drawing.Point MakePoint(int x, int y);
[DllImport("SimpleDll")] public static extern IntPtr MakePointIndirect(int x, int y);
[DllImport("SimpleDll")] public static extern int GetPointY(System.Drawing.Point p);
[DllImport("SimpleDll")] public static extern int GetPointYIndirect(ref System.Drawing.Point pp);
[DllImport("SimpleDll")] public static extern int SumIntegers(ref int firstElem, int size);
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-06-10 06:46:24

或者可以试着用

代码语言:javascript
复制
[DllImport("SimpleDll")]
public static extern IntPtr ReturnString();

在您的调用代码中,使用Marshal类

代码语言:javascript
复制
string ret = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(PInvoke.ReturnString());
票数 33
EN

Stack Overflow用户

发布于 2016-07-31 03:16:09

也可以使用自定义封送拆收器来完成此操作:

代码语言:javascript
复制
class ConstCharPtrMarshaler : ICustomMarshaler
{
    public object MarshalNativeToManaged(IntPtr pNativeData)
    {
        return Marshal.PtrToStringAnsi(pNativeData);
    }

    public IntPtr MarshalManagedToNative(object ManagedObj)
    {
        return IntPtr.Zero;
    }

    public void CleanUpNativeData(IntPtr pNativeData)
    {
    }

    public void CleanUpManagedData(object ManagedObj)
    {
    }

    public int GetNativeDataSize()
    {
        return IntPtr.Size;
    }

    static readonly ConstCharPtrMarshaler instance = new ConstCharPtrMarshaler();

    public static ICustomMarshaler GetInstance(string cookie)
    {
        return instance;
    }
}

并像这样使用它:

代码语言:javascript
复制
[DllImport("SimpleDll")]
[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(ConstCharPtrMarshaler))]
public static extern string ReturnString();
票数 15
EN

Stack Overflow用户

发布于 2011-06-10 06:46:58

处于发布模式的C++编译器将常量放入受保护的数据页中;试图将其传递给C#会导致问题。在调试模式下,编译器不会优化数据页中的常量,因此不存在保护问题。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6300093

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档