none
急!c#调用vc dll输出参数的问题 RRS feed

  • 问题

  • 我的vc++的dll如下

    extern "C" _declspec(dllexport) BOOL GetImportTable(char *file,char *dll,char *import);	
    //dll和import会得到一串字符串,在c#那边想获取到
    BOOL GetImportTable(char* file,char* dll,char* import)
    {
    	string dllName(dll);
    	string name(import);
    	if (m_GetImportTable(file, dllName, name))
    	{
    		dll = (char*)dllName.c_str();
    		import = (char*)name.c_str();
    		return TRUE;
    	}
    	else
    	{
    		return FALSE;
    	}
    
    
    } 

    在c#中调用为

     [DllImport("xxx.dll",ExactSpelling=false,CallingConvention=CallingConvention.Cdecl)]
    
            public static extern bool GetImportTable(StringBuilder file, StringBuilder dll, StringBuilder import);
    
    public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click_1(object sender, EventArgs e)
            {
                string file = textBoxFilePath.Text;
                foreach (string filePath in Directory.EnumerateFiles(file, "*.*", SearchOption.AllDirectories))
                {
                    StringBuilder fileSB = new StringBuilder(filePath);
                    StringBuilder dll = new StringBuilder();
                    StringBuilder import = new StringBuilder();
                    bool isSuccess = GetImportTable(fileSB,dll,import);
                    textBoxLog.Text = textBoxLog.Text + filePath + " " + dll + "\r\n";
                    
                }                                                                                                                                                                                                                                                                                                                             

    返回结果是true,但是这样获取不到dll这个变量从dll那边传过来的值

    还有一个问题就是如果vc是传地址的,c#中又该怎样调用和获取值,vc传地址如下

    BOOL GetImportTable(char* file,string &dll,string &import)
    {
    	return (GetImportTable(file,dll,import);
    } //dll和import会得到一串字符串,在c#那边想获取到

    麻烦各位高手帮忙解答下,对c#不熟



    • 已编辑 xc19 2013年1月25日 5:42
    2013年1月25日 5:38

答案

全部回复

  • char* 用 StringBuilder 没问题,注意 CharSet 设置要和你的 DLL 对应,另外在传入前要先分配足够大的空间,例如:

    StringBuilder dll = new StringBuilder(3000);

    & 可以用 ref 关键字。

    2013年1月25日 6:26
  • 能麻烦改写下我看看吗,因为在调试的时候 StringBuilder dll始终是空的

    数据是要从vc dll那边传输进来给c# StringBuilder dll


    • 已编辑 xc19 2013年1月25日 7:32
    2013年1月25日 7:28
  • 能麻烦改写下我看看吗,因为在调试的时候 StringBuilder dll始终是空的

    StringBuilder fileSB = new StringBuilder(filePath);
    StringBuilder dll = new StringBuilder(30000);
    StringBuilder import = new StringBuilder(30000);
    bool isSuccess = GetImportTable(fileSB,dll,import);
    2013年1月25日 7:33
  • 这个我知道 是如何获取数值那里

    ”& 可以用 ref 关键字。“

    这个不懂,能把dll如何获取数值写一下吗 麻烦了

    2013年1月25日 7:42
  • 这个我知道 是如何获取数值那里

    ”& 可以用 ref 关键字。“

    这个不懂,能把dll如何获取数值写一下吗 麻烦了

    啥数值?是不是这样:

    win32 api : void GetNumber(int& a);

    C# : void GetNumber(ref int a); 或者 void GetNumber(out int a);


    • 已编辑 Skyseer 2013年1月25日 7:52
    2013年1月25日 7:51
  • vc:BOOL GetImportTable(char* file,char* dll,char* import)

    c#:public static extern bool GetImportTable(StringBuilder file, ref StringBuilder dll,ref StringBuilder import);

    然后 vc那边char* dll,char* import运行后有两个字符串数组传过来

    c#这边 ref StringBuilder dll,ref StringBuilder import要怎么接受,,调试看到 整个过程都成功,但这两个变量是空的

    2013年1月25日 7:57
  • vc:BOOL GetImportTable(char* file,char* dll,char* import)

    c#:public static extern bool GetImportTable(StringBuilder file, ref StringBuilder dll,ref StringBuilder import);

    然后 vc那边char* dll,char* import运行后有两个字符串数组传过来

    c#这边 ref StringBuilder dll,ref StringBuilder import要怎么接受,,调试看到 整个过程都成功,但这两个变量是空的

    虽然我一开始就觉得你的C++接口定义错误,但是我还是仔细看了你写的C++代码,我发现一个问题,就是你错误的使用了 std::string 的构造函数:

    std::string 的构造函数 __CLR_OR_THIS_CALL basic_string(const _Elem *_Ptr) ,会开辟新的内存空间,将 _Ptr 拷贝到新的空间里,而你的两个局部变量 dllname 和 name 会在作用域结束时被回收,所以你这样的代码:

    dll = (char*)dllName.c_str();
    import = (char*)name.c_str();


    会得到两个非法的指针。

    我建议你看看Windows API 是如何来处理返回字符串变量的。

    2013年1月25日 8:13
  • vc:BOOL GetImportTable(char* file,char* dll,char* import)

    c#:public static extern bool GetImportTable(StringBuilder file, ref StringBuilder dll,ref StringBuilder import);

    然后 vc那边char* dll,char* import运行后有两个字符串数组传过来

    c#这边 ref StringBuilder dll,ref StringBuilder import要怎么接受,,调试看到 整个过程都成功,但这两个变量是空的

    我给你贴一段我的用于处理你这种情况的API:

    static DWORD GetIPAddress(LPTSTR lpAddress,DWORD dwSize)
    	{
    		const TCHAR* pszAddressDefault = _T("127.0.0.1");
    		WSADATA wsaData;    //定义一个WSADATA数据结构		
    		WORD wVersionRequested = MAKEWORD( 2, 0);    //确定Winsock的版本 也可以直接赋值:wVersionRequested=2		
    		if(WSAStartup(wVersionRequested, &wsaData) == 0)  //对Winsock DLL进行初始化
    		{  
    			CHAR szHostName[FIXED_STR_128] ={0};
    			if(gethostname(szHostName, FIXED_STR_128) == 0)   //获取主机名
    			{  
    				PHOSTENT hostinfo = gethostbyname(szHostName);
    				if(hostinfo != NULL)   //判断主机名转成IP是否成功
    				{ 
    					USES_CONVERSION;
    					_stprintf_s(lpAddress,dwSize,_T("%s"),A2T(inet_ntoa (*(struct in_addr *)*hostinfo->h_addr_list)));
    					return S_OK;
    				}  
    			}  
    			WSACleanup();  //中止Windows Sockets DLL的使用
    		}
    		_stprintf_s(lpAddress,dwSize,_T("%s"),pszAddressDefault);
    		return GetLastError();
    	}

    2013年1月25日 8:16
  • 我把这些处理全在dll 里面完成了 

    然后返回bool值

    谢谢解答

    2013年1月28日 3:10