2016-08-03 44 views
0

我目前正在與FANUC 31i B型控制器進行通信。我的目標是能夠上傳零件程序,確認沒有數據丟失,並在需要時刪除程序。C#:將指針傳遞給字符串以保存返回的值

FANUC有一個FOCAS庫,其中有用於C#的有用函數。下面是我遇到麻煩的DllImport。

/* read selected file name */ 
[DllImport("FWLIB64.dll", EntryPoint="cnc_pdf_rdmain")] 
public static extern short cnc_pdf_rdmain(ushort FlibHndl, [Out,MarshalAs(UnmanagedType.AsAny)] Object a); 

根據自己的技術團隊,我需要一個指針傳遞給一個字符串來保存存儲在一個對象返回值。該字符串是剛剛上傳到系統的零件程序的文件路徑。這對我來說很重要,因爲它可以讓我選擇上傳的程序作爲主程序。

這是我用我的主要代碼是什麼:

Object mg1 = new object(); 
     rslt = Focas64.cnc_pdf_rdmain(this.i31Handle,); 
     if (rslt != 0) 
     { 
      StopActivity(true); 
      return; 
     } 

我不是太熟悉C#或編碼爲此事。所以請爲我貶低它。謝謝!

+0

爲什麼C++代碼,當您使用C#?他們是不同的語言。 –

+0

FOCAS庫最初是爲C++設計的。我認爲這在這種情況下是相關的。我現在將其刪除 –

+0

C或C++頭文件中'cnc_pdf_rdmain'函數的確切簽名是什麼? – cynic

回答

0

我能解決下面這個問題是工作代碼:

 // Verify code 
     byte[] a = new byte[244]; 
     rslt = Focas64.cnc_pdf_rdmain(this.i31Handle, a); 
     string result = System.Text.Encoding.UTF8.GetString(a); 
     if (rslt != 0) 
     { 
      StopActivity(true, Convert.ToString(rslt), this.tDownloadls, true); 
      return; 
     } 
0

我對你談論的FANUC產品瞭解不多,但是這裏有一些字符串基礎知識。
您可以創建這樣

string myString; 

一個字符串,然後獲得一個指向它像這樣

&myString; 

所以,你的代碼可能看起來像這樣

string myString; 
rslt = Focas64.cnc_pdf_rdmain(this.i31Handle, &myString); 
+0

請注意,如果您處於不安全塊中,則只能取消引用指針,而C#編譯器只會讓您使用不安全的代碼(如果明確告知),這一點很重要。 https://msdn.microsoft.com/zh-cn/library/aa288474(v=vs.71).aspx –

+0

參數 FlibHndl [in] 指定庫句柄。有關詳細信息,請參閱「庫處理」。 file_path [out] 指定存儲「當前驅動器+文件夾+文件名」的字符串的指針。 爲242個字符的字符串最大大小分配244個字節長度。該字符串是NULL終止的。 –

+0

可能這可能會幫助你理解cnc_pdf_rdmain中所需的參數 –

0

您可以使用下面的建議:

[DllImport("FWLIB64.dll", EntryPoint="cnc_pdf_rdmain")] 

public static unsafe extern short cnc_pdf_rdmain(ushort FlibHndl, [ Out, MarshalAs(UnmanagedType.AsAny) ] out Object a); 

Object mg1 = new object(); 
rslt = Focas64.cnc_pdf_rdmain(this.i31Handle, out mg1); 
if (rslt != 0) 
{ 
    StopActivity(true); 
    return; 
} 
string result = mg1.ToString(); 
Console.WriteLine(result); 
+0

我已經試過了,它會拋出下面的異常:SpaceX中出現'System.Runtime.InteropServices.MarshalDirectiveException' - DragonHPC.exe 附加信息:無法編組'參數#2':AsAny不能用於返回類型,ByRef參數,ArrayWithOffset或從非託管傳遞到託管的參數。 –

+0

'AsAny'是一種便宜的佔位符,並不總是像您所期望的那樣工作。我通常不會在.NET中使用pinvoke/export的東西,但是如果你有一個技術文檔(顯示預期的數據類型,可能在C/C++中),這會有所幫助。否則,如果使用32位,請嘗試將「AsAny」更改爲int類型(或者,如果是64位,則嘗試long類型)。這些是基本的C風格指針類型,然後將'&myString'指針傳遞給它(不要回想起來,這些東西可能是一個真正的痛苦,尤其是對於外行) – jleach

+0

我不相信你可以使用字符串類型爲指針。 –

0

dllimport行很奇怪。我不確定爲什麼FANUC在你知道這個類型的時候給了你(char *)。將字符串編組爲char *有一個簡單的過程。你需要知道char *是ANSI還是寬編碼。

通常你會使用類似MarshalAs(UnmanagedType.LPStr)],即

[DllImport ("does-not-exist")] 
private static extern void Foo (
     [Out, MarshalAs(UnmanagedType.LPStr)] string ansiString) 

而且,你會希望大小字符串第一所以有空間來寫它。因此,使字符串長244字符

string s = new string(' ',244); 
Focas64.cnc_pdf_rdmain(this.i31Handle, s); 

已經有一段時間了。我剛剛刷新了我的知識here

+0

希望這有效。我將能夠在2小時內進行測試。數控機牀目前沒有電力=( –

0

我不認爲你正在使用正確的Fanuc函數來執行你想要做的事情。 函數cnc_pdf_rdmain用於獲取機器上註冊的主程序的路徑。你不能用這個函數影響它,你不能用這個函數下載它。它只會告訴你路徑。

我有這個工作在VB中。淨

從Fanuc的文檔首先:

#include "fwlib32.h" or "fwlib64.h" 
FWLIBAPI short WINAPI cnc_pdf_rdmain(unsigned short FlibHndl, char *file_path); 

而且VB聲明:

Declare Function cnc_pdf_rdmain Lib "FWLIB32.DLL" _ 
    (ByVal FlibHndl As Integer, <[In], Out> ByVal a() As Char) As Short 

(這是從Fanuc的預交付)

現在,在我的應用程序:

Dim mpPath As Char() 
ReDim mpPath(212) 

LastError = cnc_pdf_rdmain(Hndl, mpPath) 

(LastError被定義爲Integer,而Hndl是前面建立的Focas連接的句柄。注意在Fanuc文檔中指定了Char陣列的大小)

這將在mpPath中返回一個字符串,如下所示:「// CNC_MEM/1234」如果程序1234作爲主程序從頂層加載目錄。