GetModulePara in C# verwenden
Ein TcCOM-Objekt stellt seine Parameter über das Interface ITcModuleInstance bereit. Jeder Parameter wird über eine numerische **Parameter-ID (PID)** angesprochen, die aus der TMC-Beschreibung des Moduls stammt. Dieser Artikel zeigt, wie man Parameterwerte über das Automation Interface in C# ausliest und dabei korrekt in den richtigen .NET-Typ überführt.
Der zentrale Stolperstein: GetModulePara liefert die Daten typlos als rohe Bytes zurück. Ohne Kenntnis des Parametertyps lassen sich diese Bytes nicht sinnvoll interpretieren. Die folgenden drei Regeln zeigen, wie man je nach Situation zum richtigen Wert kommt.
Voraussetzungen
Voraussetzung ist ein geöffnetes TwinCAT-Projekt mit einem TcCOM-Objekt, dessen Tree-Item bereits vorliegt. In den Beispielen ist treeItem das per LookupTreeItem ermittelte Objekt, das zu ITcModuleInstance gecastet wird:
var mi = (ITcModuleInstance)treeItem;
Die verwendete pid (z.B. 0x050300B1) ist die Parameter-ID aus der TMC-Beschreibung des Moduls.
Was GetModulePara zurückgibt
GetModulePara gibt einen VARIANT zurück, der ein Byte-Array mit VT_ARRAY | VT_UI1 enthält. Das sind rohe Bytes im Little-Endian-Format, ohne Typinformation. In C# kommt dieser VARIANT als byte[] an.
Weil die Bytes keine Typinformation tragen, muss der Aufrufer wissen, wie viele Bytes der Parameter belegt und wie sie zu deuten sind. Ohne die TMC-Beschreibung des Moduls — oder einen vorherigen Aufruf von GetTypeOfModulePara — sind die Bytes nicht korrekt zu interpretieren.
Welche Funktion für welchen Fall
Die folgende Tabelle fasst zusammen, welche der drei Zugriffsfunktionen sich für welchen Parametertyp eignet:
|
Situation |
Empfehlung |
|---|---|
|
Parameter ist |
|
|
Parameter ist |
|
|
Typ ist unbekannt |
|
GetModuleParaDWORD für skalare Parameter
Für alle skalaren Parameter bis zu 4 Byte Größe ist GetModuleParaDWORD die einfachste Wahl. Die Funktion liefert direkt einen uint, sodass Byte-Arrays nicht notwendig sind. Der Rückgabewert wird anschließend auf den tatsächlichen Typ des Parameters gecastet:
var mi = (ITcModuleInstance)treeItem;
uint pid = 0x050300B1;
uint rawValue = mi.GetModuleParaDWORD(pid);
// Cast according to type:
int asInt = (int)rawValue;
bool asBool = rawValue != 0;
GetModulePara + BitConverter für größere Typen
Parameter mit mehr als 4 Byte — etwa LREAL (8 Byte) oder LINT (8 Byte) — sowie Structs lassen sich nicht über GetModuleParaDWORD lesen. Hier holen Sie das rohe Byte-Array über GetModulePara und wandeln es mit BitConverter in den Zieltyp um. Wichtig ist, die zum Parametertyp passende BitConverter-Methode zu wählen, da die Bytes im Little-Endian-Format vorliegen:
var mi = (ITcModuleInstance)treeItem;
uint pid = 0x050300B1;
byte[] bytes = (byte[])mi.GetModulePara(pid);
// LREAL (= double, 8 bytes):
double position = BitConverter.ToDouble(bytes, 0);
// LINT (= long, 8 bytes):
long lint = BitConverter.ToInt64(bytes, 0);
// DINT (= int, 4 bytes):
int dint = BitConverter.ToInt32(bytes, 0);
GetTypeOfModulePara + ITcTypeInstance.Name
Ist der Typ eines Parameters zur Entwicklungszeit nicht bekannt, lässt er sich zur Laufzeit über GetTypeOfModulePara ermitteln. Die Funktion liefert ein ITcTypeInstance-Objekt, dessen .Name-Eigenschaft den Typnamen direkt als lesbaren String zurückgibt — ein Vergleich gegen Magic Numbers ist nicht nötig. Mit diesem Typnamen wählen Sie anschließend die passende Konvertierung für das von GetModulePara gelieferte Byte-Array:
var mi = (ITcModuleInstance)treeItem;
uint pid = 0x050300B1;
mi.GetTypeOfModulePara(pid, out ITcTypeInstance typeInstance);
string typeName = typeInstance.Name; // e.g. "LREAL", "UDINT", "BOOL", "DINT"
byte[] bytes = (byte[])mi.GetModulePara(pid);
object value = typeName switch {
"LREAL" => BitConverter.ToDouble(bytes, 0),
"LINT" => BitConverter.ToInt64(bytes, 0),
"DINT" => BitConverter.ToInt32(bytes, 0),
"UDINT" or "DWORD" => BitConverter.ToUInt32(bytes, 0),
"INT" => BitConverter.ToInt16(bytes, 0),
"UINT" or "WORD" => BitConverter.ToUInt16(bytes, 0),
"BOOL" => bytes[0] != 0,
_ => bytes // Struct or unknown type — return raw bytes
};
Der _-Zweig fängt Structs und unbekannte Typen ab und gibt das rohe Byte-Array zurück. Für zusammengesetzte Typen lässt sich der genaue Aufbau bei Bedarf über ITcTypeInstance.IecDeclaration ermitteln und das Byte-Array entsprechend zerlegen.
![]() | Damit ist Regel 3 der robusteste Weg, wenn der Parametertyp zur Entwicklungszeit nicht feststeht. Er funktioniert für alle skalaren Typen ohne vorheriges Wissen über die Bytegröße. Für bekannte skalare Parameter bleibt Regel 1 die einfachste Lösung. Details zum zurückgegebenen Typdeskriptor finden sich im Artikel ITcTypeInstance. |
