日期:2014-05-18  浏览次数:20997 次

求助,C#调用C++动态链接库
小弟要测试一个C++动态链接库在C#下的调用情况 无奈对C#一窍不通 特来求助大家
C/C++ code

#include<string.h>
#include<stdio.h>

typedef struct _TAG_Info
{
    char tagMac[64];
    char tagCoordinate[32];
}TAG_INFO;


typedef struct _RSSI_Info
{
    short nRSSI;
    char strCoordinate[32];
}RSSI_INFO;
TAG_INFO result;


extern"C" _declspec(dllexport) TAG_INFO _stdcall GetCoordinateByTagsRssi(char tagMac[64],short inAPCount,RSSI_INFO*pRssiInfo)
{
    
    
    sprintf(result.tagCoordinate,"x:%f,y:%f",10.0,10.0);
    strcpy(result.tagMac,tagMac);
        return result;
}//C++的动态链接库代码   省略了算法  如果调用成功 就能显示出x:10.0000,y:10.0000   在VC6.0下调用正常



下面是小弟写的C#调用代码 很多问题 都是数据类型之间的关系搞不清楚
C# code

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Cstest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        [StructLayout(LayoutKind.Sequential)]
        
        public struct TAG_INFO
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
            public string tagMac;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string tagCoordinate;
        };


        public struct RSSI_INFO
        {
            public Int16 nRSSI;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string strCoordinate;
        };//对应上面两个结构体  但是char数组和string对应总觉得不太对,又不知道该用什么
        [DllImport(@"E:\dll\Debug\dlltest.dll", EntryPoint = "_GetCoordinateByTagsRssi@12")]
        public static extern TAG_INFO GetCoordinateByTagsRssi(string tagMac, Int16 inAPCount, ref RSSI_INFO pRssiInfo);
        private void button1_Click(object sender, EventArgs e)
        {

            TAG_INFO jieguo;

            RSSI_INFO[] test = new RSSI_INFO[3];
            test[0].nRSSI = 5;
            test[1].nRSSI = 5;
            test[2].nRSSI = 5;
            
            test[0].strCoordinate = "x:0,y:5";
             test[1].strCoordinate = "x:5,y:0";
             test[2].strCoordinate = "x:10,y:5";

            string tagmac ="AAAA";
           
            Int16 m = 3;
            jieguo = GetCoordinateByTagsRssi(tagmac, m, ref test[0]);
        }
    }
}


编译能通过 但是一点button 就会出现“方法的类型签名与 PInvoke 不兼容。”
资料也查了不少 无奈C#懂得太少 只好麻烦各位

------解决方案--------------------
http://www.cnblogs.com/warensoft/archive/2011/12/09/Warenosoft3D.html
------解决方案--------------------
1、要用[StructLayout( LayoutKind.Sequential)]防止.net进行结构优化。
2、用RSSI_INFO[] pRssiInfo而不是ref RSSI_INFO pRssiInfo,保证在PInvoke的时候,所有的数组成员不会被CLR移动。
3、要用byte[] tagMac,不然就要指定封送方式:[MarshalAs(...)] string tagMac。
------解决方案--------------------
lz需要做好c#调用c++dll时的数据类型对应。这里总结得挺好:
http://blog.csdn.net/xqf222/article/details/5877795
------解决方案--------------------
C# code
class Program
    {
        public const int tagMac_BytesCount = 64;
        public const int tagCoordinate_BytesCount = 32;
        public const int tagAll_BytesCount = tagMac_BytesCount + tagCoordinate_BytesCount;

        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
        public struct TAG_INFO
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = tagMac_BytesCount)]
            public String tagMac;
            [MarshalAs(Un