DLL中:
void Test(void* param)
{
int* temp = (int*)param;
*temp = 253;
}
C#中调用DLL中Test函数:   
 class Program
    {
        [DllImport("CIntToVoidPointerDLL2.dll")]
        public static extern void Test(IntPtr param);
        static void Main(string[] args)
        {
            IntPtr a = new IntPtr(34);
            Test(a);
            Console.WriteLine((int)a);
        }
    }
运行提示:未处理的异常:System.AccessViolationException:尝试读取或写入受保护的内存。这通常指示其他内存已损坏。这样写有什么错误?
还有,简单类型如何传递给DLL中参数为void*的函数?现在可以传递struct,简单类型却搞不定。谢谢

解决方案 »

  1.   

    class Program
      {
      [DllImport("CIntToVoidPointerDLL2.dll")]
      public static extern void Test(ref int param);
      static void Main(string[] args)
      {
      int a = 34;
      Test(ref a);
      Console.WriteLine((int)a);
      }
      }既然DLL中是作为int类型的指针,上面的就可以了
    如果一定要声明为[DllImport("CIntToVoidPointerDLL2.dll")]
      public static extern void Test(IntPtr param);//申请一个int类型大小的空间
    IntPtr a = Marshal.AllocHGlobal(4);
    Marshal.WriteInt32(a,34);
    Test(a);
    int b=Marshal.ReadInt32(a);
    Marshal.FreeHGlobal(a);
    Console.WriteLine(b);http://msdn.microsoft.com/zh-cn/library/atxe881w(v=VS.80).aspx
      

  2.   

    类型问题
    public static extern void Test(ref int param);
    int a = 34;
    Test(ref a);IntPtr i= Marshal.AllocHGlobal(len);
    分配空间
      

  3.   

    由于非托管dll在导出非托管函数时会采用一些不同的调用约定,在某些情况下如果使用默认的调用约定就可能出现无法正确调用非托管函数的情况,因此必须显示的制定调用约定既DllImport数次那个中的CallingConvention字段,CallingConvention字段定义了调用约定,CallingConvention可以取的所有值如下:Cdecl : 调用方既托管代码方负责清理堆栈,这就使得开发人员能够调用具有可变参数的函数,使之可用于接收可变数目的参数的方法StdCall: 被调用方既非托管代码函数负责清理堆栈,这是在windows操作系统下使用平台调用非托管代码的默认调用约定1.声明应该加上CallingConvention,指明是cdecl
    2.
      IntPtr a = new IntPtr(34);
      Test(a);
      Console.WriteLine((int)a);//a是int的指针,并且这个指针初始化指向了错误的内存。
    应该这么写:
                int myInt;
                int* pInt = &myInt;
                IntPtr ptr = new IntPtr(pInt);
                Test(ptr);
      

  4.   

    改之后就是这个样子:
            [DllImport("CIntToVoidPointerDLL2.dll",CallingConvention=CallingConvention.Cdecl)]
            public static extern void Test(IntPtr param);
            static unsafe void Main(string[] args) {
                int myInt;
                int* pInt = &myInt;
                IntPtr ptr = new IntPtr(pInt);
                Test(ptr);        }
      

  5.   

    用ref int做参数实际上也是一样。ref int 实际上就是传递int的指针,同样需要指定CallingConvention.