- C#/.NET API: fixed problem with boolean marshalling together with VC++ compiled DLL

pull/6/head
Michael Zillgith 11 years ago
parent 0941e2a971
commit 78a694c5d3

@ -100,8 +100,6 @@ namespace IEC61850
/// </summary>
public class ControlObject
{
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern LastApplErrorInternal ControlObjectClient_getLastApplError(IntPtr self);
@ -114,16 +112,20 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
private static extern int ControlObjectClient_getControlModel(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool ControlObjectClient_operate(IntPtr self, IntPtr ctlVal, UInt64 operTime);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool ControlObjectClient_select(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool ControlObjectClient_selectWithValue(IntPtr self, IntPtr ctlVal);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private static extern bool ControlObjectClient_cancel(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]

@ -54,7 +54,8 @@ namespace IEC61850
[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
static extern float MmsValue_toFloat (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
static extern bool MmsValue_getBoolean (IntPtr self);
[DllImport ("iec61850", CallingConvention=CallingConvention.Cdecl)]
@ -135,8 +136,8 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedConnection_deleteDataSet (IntPtr self, out int error, string dataSetReference);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr IedConnection_getDataSetDirectory (IntPtr self, out int error, string dataSetReference, out bool isDeletable);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr IedConnection_getDataSetDirectory(IntPtr self, out int error, string dataSetReference, [MarshalAs(UnmanagedType.I1)] out bool isDeletable);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr IedConnection_getMmsConnection (IntPtr self);
@ -892,13 +893,33 @@ namespace IEC61850
if (error != 0)
throw new IedConnectionException ("Failed to delete data set", error);
}
}
/// <summary>
/// Get the directory of the data set.
/// </summary>
/// <description>This function returns a list of object references with appended functional constraints (FC) of the data set elemenents.</description>
/// <param name="dataSetReference">The object reference of the data set</param>
/// <returns>the list of object references</returns>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public List<string> GetDataSetDirectory(string dataSetReference)
{
bool isDeletable;
return GetDataSetDirectory(dataSetReference, out isDeletable);
}
/// <summary>
/// Get the directory of the data set.
/// </summary>
/// <description>This function returns a list of object references with appended functional constraints (FC) of the data set elemenents.</description>
/// <param name="dataSetReference">The object reference of the data set</param>
/// <param name="isDeletable">Indication if this data set is permanent or deletable.</param>
/// <returns>the list of object references</returns>
/// <exception cref="IedConnectionException">This exception is thrown if there is a connection or service error</exception>
public List<string> GetDataSetDirectory (string dataSetReference)
public List<string> GetDataSetDirectory (string dataSetReference, out bool isDeletable)
{
int error;
bool isDeletable;
IntPtr linkedList = IedConnection_getDataSetDirectory (connection, out error, dataSetReference, out isDeletable);

@ -1,46 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{C35D624E-5506-4560-8074-1728F1FA1A4D}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>iec61850dotnet</RootNamespace>
<AssemblyName>iec61850dotnet</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="MmsValue.cs" />
<Compile Include="DataSet.cs" />
<Compile Include="ReportControlBlock.cs" />
<Compile Include="IEC61850ClientAPI.cs" />
<Compile Include="Reporting.cs" />
<Compile Include="Control.cs" />
<Compile Include="IsoConnectionParameters.cs" />
<Compile Include="MmsVariableSpecification.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{C35D624E-5506-4560-8074-1728F1FA1A4D}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>iec61850dotnet</RootNamespace>
<AssemblyName>iec61850dotnet</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="MmsValue.cs" />
<Compile Include="DataSet.cs" />
<Compile Include="ReportControlBlock.cs" />
<Compile Include="IEC61850ClientAPI.cs" />
<Compile Include="Reporting.cs" />
<Compile Include="Control.cs" />
<Compile Include="IsoConnectionParameters.cs" />
<Compile Include="MmsVariableSpecification.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

@ -46,7 +46,8 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern double MmsValue_toDouble (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
static extern bool MmsValue_getBoolean (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
@ -61,7 +62,8 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void MmsValue_setBitStringBit(IntPtr self, int bitPos, bool value);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
static extern bool MmsValue_getBitStringBit(IntPtr self, int bitPos);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
@ -130,7 +132,8 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr MmsValue_getOctetStringBuffer(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
static extern bool MmsValue_equals(IntPtr self, IntPtr otherValue);

@ -55,7 +55,8 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedConnection_setRCBValues (IntPtr connection, out int error, IntPtr rcb, UInt32 parametersMask, bool singleRequest);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_isBuffered (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
@ -65,12 +66,14 @@ namespace IEC61850
static extern void ClientReportControlBlock_setRptId (IntPtr self, string rptId);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_getRptEna (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setRptEna (IntPtr self, bool rptEna);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setRptEna(IntPtr self, bool rptEna);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_getResv (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
@ -112,13 +115,15 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setIntgPd (IntPtr self, UInt32 intgPd);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_getGI (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void ClientReportControlBlock_setGI (IntPtr self, bool gi);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReportControlBlock_getPurgeBuf (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]

@ -67,7 +67,8 @@ namespace IEC61850
public class Report
{
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReport_hasTimestamp (IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
@ -79,28 +80,34 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern int ClientReport_getReasonForInclusion(IntPtr self, int elementIndex);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReport_hasSeqNum(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt16 ClientReport_getSeqNum(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReport_hasDataSetName(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReport_hasReasonForInclusion(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReport_hasConfRev(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 ClientReport_getConfRev(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReport_hasBufOvfl(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
static extern bool ClientReport_hasDataReference(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]

@ -34,6 +34,7 @@
#include "mms_value_internal.h"
#define DEFAULT_CONNECTION_TIMEOUT 10000
#define DATA_SET_MAX_NAME_LENGTH 64 /* is 32 according to standard! */
typedef struct sICLogicalDevice
{
@ -1827,7 +1828,7 @@ IedConnection_createDataSet(IedConnection self, IedClientError* error, const cha
{
char domainIdBuffer[65];
char itemIdBuffer[33]; /* maximum data set name = 32 chars */
char itemIdBuffer[DATA_SET_MAX_NAME_LENGTH + 1];
const char* domainId;
const char* itemId;
@ -1899,7 +1900,7 @@ void
IedConnection_deleteDataSet(IedConnection self, IedClientError* error, const char* dataSetReference)
{
char domainId[65];
char itemId[33];
char itemId[DATA_SET_MAX_NAME_LENGTH + 1];
bool isAssociationSpecific = false;
int dataSetReferenceLength = strlen(dataSetReference);
@ -1912,7 +1913,7 @@ IedConnection_deleteDataSet(IedConnection self, IedClientError* error, const cha
const char* itemIdString = dataSetReference + strlen(domainId) + 1;
if (strlen(itemIdString) > 32) {
if (strlen(itemIdString) > DATA_SET_MAX_NAME_LENGTH) {
*error = IED_ERROR_OBJECT_REFERENCE_INVALID;
goto exit_function;
}
@ -1953,7 +1954,7 @@ IedConnection_getDataSetDirectory(IedConnection self, IedClientError* error, con
LinkedList dataSetMembers = NULL;
char domainIdBuffer[65];
char itemIdBuffer[129];
char itemIdBuffer[DATA_SET_MAX_NAME_LENGTH + 1];
const char* domainId = NULL;
const char* itemId = NULL;
@ -1962,9 +1963,22 @@ IedConnection_getDataSetDirectory(IedConnection self, IedClientError* error, con
if (dataSetReference[0] != '@') {
domainId = MmsMapping_getMmsDomainFromObjectReference(dataSetReference, domainIdBuffer);
char* itemIdRef = copyStringToBuffer(dataSetReference + strlen(domainId) + 1, itemIdBuffer);
StringUtils_replace(itemIdRef, '.', '$');
itemId = itemIdRef;
if (domainId == NULL) {
*error = IED_ERROR_OBJECT_REFERENCE_INVALID;
goto exit_function;
}
const char* itemIdRef = dataSetReference + strlen(domainId) + 1;
if (strlen(itemIdRef) > DATA_SET_MAX_NAME_LENGTH) {
*error = IED_ERROR_OBJECT_REFERENCE_INVALID;
goto exit_function;
}
char* itemIdRefInBuffer = copyStringToBuffer(itemIdRef, itemIdBuffer);
StringUtils_replace(itemIdRefInBuffer, '.', '$');
itemId = itemIdRefInBuffer;
}
else {
itemId = dataSetReference + 1;
@ -2006,6 +2020,7 @@ IedConnection_getDataSetDirectory(IedConnection self, IedClientError* error, con
*error = iedConnection_mapMmsErrorToIedError(mmsError);
exit_function:
return dataSetMembers;
}
@ -2014,7 +2029,7 @@ IedConnection_readDataSetValues(IedConnection self, IedClientError* error, const
ClientDataSet dataSet)
{
char domainIdBuffer[65];
char itemIdBuffer[129];
char itemIdBuffer[DATA_SET_MAX_NAME_LENGTH + 1];
const char* domainId = NULL;
const char* itemId = NULL;
@ -2023,7 +2038,21 @@ IedConnection_readDataSetValues(IedConnection self, IedClientError* error, const
if (dataSetReference[0] != '@') {
domainId = MmsMapping_getMmsDomainFromObjectReference(dataSetReference, domainIdBuffer);
char* itemIdRef = copyStringToBuffer(dataSetReference + strlen(domainId) + 1, itemIdBuffer);
if (domainId == NULL) {
*error = IED_ERROR_OBJECT_REFERENCE_INVALID;
goto exit_function;
}
const char* itemIdRefOrig = dataSetReference + strlen(domainId) + 1;
if (strlen(itemIdRefOrig) > DATA_SET_MAX_NAME_LENGTH) {
*error = IED_ERROR_OBJECT_REFERENCE_INVALID;
goto exit_function;
}
char* itemIdRef = copyStringToBuffer(itemIdRefOrig, itemIdBuffer);
StringUtils_replace(itemIdRef, '.', '$');
itemId = itemIdRef;
}
@ -2045,7 +2074,7 @@ IedConnection_readDataSetValues(IedConnection self, IedClientError* error, const
if (dataSetVal == NULL) {
*error = iedConnection_mapMmsErrorToIedError(mmsError);
goto cleanup_and_exit;
goto exit_function;
}
else
*error = IED_ERROR_OK;
@ -2059,7 +2088,7 @@ IedConnection_readDataSetValues(IedConnection self, IedClientError* error, const
MmsValue_update(dataSetValues, dataSetVal);
}
cleanup_and_exit:
exit_function:
return dataSet;
}

Loading…
Cancel
Save