2013-07-12 54 views
0

我是一名爲我大學化學系工作的學生。去年,我編寫了一個C++程序來控制一個picomotor舞臺,並使它與一個力壓力傳感器進行通信,使舞臺上下移動,直到它接觸到傳感器。我使用公司提供的DLL編寫該程序。我花了一段時間,但我得到了一切工作。C中的按位運算#

今年,我將第二階段加入到程序中,並使用C#將整個程序更新爲GUI。第二階段和力傳感器只提供與C#一起工作的DLL,而舊階段則用於C++。我能夠讓所有這三個人在新的C#GUI程序中工作,這幾乎可以解決這個問題:

在舊程序中,我能夠確定舞臺上的電機是否正在通過此功能移動:

#define MOTOR_MOVING 0x01 
byte isMoving = LdcnGetStat(pico_addr) & MOTOR_MOVING; 

字節LdcnGetStat(字節地址)返回模塊在給定地址的最後一個狀態字節。根據我的指導手冊,當電動機移動時,位0被設置。因此,如果我在C++程序中使用bool變量對其進行測試,則當電機不移動時isMoving爲0,當它們位於1時,isMoving爲0,電機停止移動後立即返回0。工作正常。

但在C#中,我遇到了這個問題。我不得不做一些明確的轉換。所以我改成了這樣:

bool isMoving = Convert.ToBoolean(LdcnGetStat(pico_addr) & 
Convert.ToBoolean(MOTOR_MOVING); 

這不給我一個錯誤,但LdcnGetStat(pico_addr)將始終返回「真」,因爲它永遠不會爲0。如果我只是測試值是LdcnGetStat()吐奶當電機沒有移動時,它返回28,當它移動時,它返回s 98.如果我再次測試移動後,它返回23.

有沒有一種正確的方法來處理這在C#中?我正在考慮檢查LdcnGetStat是否返回正確的數值,但似乎並不是正確的處理方式,特別是因爲這些值似乎改變了後期移動。

謝謝

回答

2

C/C++中的條件有效地編譯成比較零。所以表達式LdcnGetStat(pico_addr) & MOTOR_MOVING相當於(LdcnGetStat(pico_addr) & MOTOR_MOVING) != 0。但是,在C#中,條件與實際的bool s完成,因此您只能使用第二個表達式。

我可以解釋更多,如果你需要我。

1

我想你要找的是什麼:

bool isMoving = (LdcnGetStat(pico_addr) & MOTOR_MOVING) != 0; 

表達:

byte isMoving = LdcnGetStat(pico_addr) & MOTOR_MOVING; 

大概爲您提供有關隱式轉換intbyte錯誤。你要投它:

byte isMoving = (byte)(LdcnGetStat(pico_addr) & MOTOR_MOVING); 

在這種情況下,isMoving將等於0x01當電機轉動。

+0

確實讓我感到厭惡的是'&'運算符似乎認爲結果類型是其操作數中較長的一個。如果任意一個操作數中的任何一個都符合無符號類型,則結果無法適應該類型。 '|'運算符通常應該假定結果類型是它的操作數的長度,但是如果其中一個是負常數,那麼可能會有一個例外(在這種情況下,結果保證適合任何可以保持該常量的類型)。 – supercat

+0

順便說一句,我也真的希望C#在int和enum類型上定義了一個方便的運算符或方法,它將測試兩個整數值的「逐位」和「非」是否爲非零。在C中,我會說'if(myFlags&THIS_FLAG)do_something();'。我認爲不必像((myFlags&THIS_FLAG)!= 0)那樣編寫它,do_something();'特別提高了易讀性。 – supercat

+0

@supercat:實際上,'byte'上的按位和算術運算符返回'Int32'。例如,即使當'b1'和'b2'被聲明爲'byte','byte b3 = b1 & b2;'也會出錯。 '字節b3 = b1 + b2'會給出相同的錯誤。另一方面,我很矛盾。可能是因爲我在C#之前在Pascal做了很多工作。 –