![]() |
Calling Parasolid From .NET Code |
<<< Using Reports | Chapters | Introduction To Basic Concepts In Parasolid >>> |
This chapter describes the Microsoft .NET binding DLL for Parasolid, which enables Parasolid functions to be called from .NET code and allows Parasolid-based applications to be written in the C# programming language. The following sections assume that you have a working knowledge of C# and some basic familiarity with .NET programming. Use of the .NET binding with Visual Basic is not supported.
An example application written in C# is supplied as part of the Parasolid Jumpstart Kit. For more information, see Section 8.3.2, “The C# Example Application for Windows”.
For more information about using Parasolid with C# see “Calling Parasolid from
C#: Implementation Advice” in the C# Example Application for Windows User Guide, supplied as part of the Parasolid Jumpstart Kit.
The .NET binding makes the Parasolid functionality available to .NET programs. It does this by calling Parasolid functions compiled from C source code: there is no version of Parasolid written in a .NET language. C# has facilities for calling C functions ( Platform Invoke, also known as P/Invoke) and for passing data with such calls.
The .NET binding is supplied as a single DLL named
pskernel_net.dll
that provides C# versions of Parasolid types, values and functions. This enables Parasolid to be called from C# or other .NET languages with compatible data-types. To call a Parasolid function, data must be stored in C# variable types that correspond to the (Parasolid) C types used in that function. The C# version of the function can then be called, which subsequently converts the data to the required C types and calls the corresponding Parasolid (C) function via P/Invoke.
Figure 12-1 Calling Parasolid functions from C#
Note: The Parasolid PK interface is fully supported. The KI functions are
not supported, although some KI token types and values are provided since they are required for PK-based programming. |
As the .NET binding is generated automatically from the Parasolid C headers, the entire interface is unsafe, requiring the use of pointers; therefore it can only be called from unsafe code blocks in C#. This minimises the performance overheads of calling Parasolid (C) functions from C#. Mixing calls to Parasolid made via the .NET binding with ones made directly from “native” code (a language that can be compiled to binary code and be called from, and also call, C) is not supported. We anticipate that users of the .NET binding will create an object-oriented layer on top of the binding, of a design suitable for their application.
Calling Parasolid (C) code from .NET code involves a performance overhead for the P/Invoke system that manages the transition. This is fairly small in most cases, usually less than 5% (and often as low as 1%), but can become appreciable for applications that make large numbers of simple attribute enquiries and changes as separate calls to Parasolid. Using the attribute callback functions (e.g.,
PK_ATTDEF_register_cb
) can reduce this overhead considerably.
The .NET binding does not use C# exceptions apart from certain rare occasions when dealing with .NET string types (see Section C.6.6, “Functions with string arguments”): instead, it returns Parasolid error codes. C# exceptions may be thrown from frustrum and callback functions, through Parasolid, to be caught by your application.
The default .NET Code Access Security settings will allow you to run .NET code that calls C code, provided that the whole program resides on the local machine. If any of it is loaded from a network machine, you must modify the Code Access Security settings, as described in the MSDN documentation library.
The .NET binding does not provide a frustrum or callback functions for use with Parasolid; you must supply these (just as you would when using Parasolid through the C interface). They may be written in native code (e.g., C or C++) or in C#. They may be registered through the C# interface as delegates, in a similar way to their usage in a native code Parasolid application. An example of a C# frustrum is provided with the C# example application.
If you register thread-specific memory allocation and freeing functions with PK_THREAD_register_memory_cbs, you must ensure that all of them are both thread-safe and capable of freeing memory allocated by a different thread’s allocator. This is because the .NET garbage collector often calls an object’s destructor from a different thread to the one that constructed the object.
The Parasolid .NET binding is written in C# and uses C# names; these consist of two to four parts, separated by periods (“.”). These periods generally correspond to the underscores (“_”) used in the corresponding name in the Parasolid C interface; however, they have more significance, as they are also scoping operators used to select members of a C#
namespace
,
class
,
struct
or
enum
as explained below.
This section describes in general how Parasolid names in C# relate to those in C. There are some additional rules to be applied in certain circumstances, which are covered in Section 12.4, “Exceptions to naming conventions in C#”.
Note: Microsoft Visual Studio offers automatic name completion when typing; this can be very useful when using the .NET binding. |
All basic C types used in the Parasolid interface have corresponding C# types, as shown below:
Note that an exception is made for
int
when appearing in the KI header files (as the type for KI token values), in which case the following conversion is done:
The PK and PK_DEBUG prefixes in the C interface become C# namespaces. There are several levels of namespace to allow for the possibility of other styles of interface. There are also some standard aliases for the C# namespaces, to make your source code more readable.
The “PK_“ field in the C# namespace for the PK prefix has the underscore “_” appended to prevent the C# compiler from becoming confused by two related concepts called “PK“. The aliases can be created in your C# code with the following statements:
using PK = PLMComponents.Parasolid.PK_.Unsafe;
using PKD = PLMComponents.Parasolid.PK_DEBUG_.Unsafe;
If you wish, you may use different aliases to those given here.
Where it exists, the upper-case word following the PK or PK_DEBUG prefix denotes the Parasolid class of a function, type or value in the C interface: examples include “BODY”, “CLASS“, “ENTITY“, “ERROR“ and “SESSION“. These classes provide a grouping mechanism for names used in programming, and reflect the logical hierarchy of entities within Parasolid; for more information concerning Parasolid classes, see Chapter 2, “Parasolid Concepts”, of the Functional Description. Note that, since Parasolid is written in C, Parasolid classes do not correspond exactly to either C++ classes or C# classes in the .NET binding.
The Parasolid class name in C, if present, becomes a C# class of the same name.
Parasolid primitive types (types of Parasolid entities and other items that give rise to classes) in C become C# structs of the same name; these structs are not members of a class.
Each primitive type has an associated null constant in the C# interface, written as “@null”; for example, PK.EDGE_t.@null, where the “@” has been inserted to avoid using a reserved word. (This is explained in Section 12.4, “Exceptions to naming conventions in C#”.)
Parasolid structures in C comprise standard forms (whose names end with
_sf_t
or
_sf_2_t
), options structures (
_o_t
), return structures (
_r_t
) and other non-specific structures whose names end in
_t
. These map to structs in C#; some are members of a class, some are not.
Parasolid token types in C become enum types in C#; these may or may not belong to a class.
For those KI token types that are necessary, the corresponding C# enum belongs to the “UNCLASSED” class in the PK namespace. This also applies to token types relating to the frustrum.
Values of Parasolid token types in C become members of the corresponding enum types in C#. For the majority of token values, the Parasolid name in C starts with the token-type name without the trailing “_t”; this is included in the C# name.
Note: There are some token values where the Parasolid name in C does not include the corresponding token-type name (up to the “_t”). In these cases, the C# name must
always include the corresponding enum type. For example, the value PK_knot_bezier_ends_c belongs to the type PK_knot_type_t; in C#, the enum member is PK.knot_type_t.bezier_ends_c. Details of all such exceptional names of token values are given in Section 12.4.3, “Special cases for names of token values”. |
For values corresponding to those KI and frustrum token types that are available, the C# names are formed as follows:
The logical type in the C interface of Parasolid is PK_LOGICAL_t; this becomes a struct named PK.LOGICAL_t in C#. The associated values PK_LOGICAL_true and PK_LOGICAL_false become struct members PK.LOGICAL_t.@true and PK.LOGICAL_t.@false, where the “@” has been inserted to avoid using a reserved word. (This is explained in Section 12.4, “Exceptions to naming conventions in C#”.)
Parasolid C functions all belong to a Parasolid class except for some of the functions used to free memory allocated by Parasolid (whose names end with
_r_f
). If a function is not a member of a Parasolid class in C, it becomes a member of the “UNCLASSED” class in C#.
Parasolid function-pointer types in C become delegates in C#. The majority (but not all) of these belong to a class.
Warning: For those function pointers that are “registered“ with Parasolid, and may be used at any subsequent time, the C# implementation necessarily produces a small memory leak each time one is registered. See Section C.6.4, “Persistent callbacks” for details. |
Each delegate has an associated null constant in the C# interface, formed by adding “_null” to the end of the name; for example, PKD.SESSION.exit_cb_t_null. It also has an associated ignore constant, formed by adding “_ignore” to the end of the name; for example, PK.FSTART.f_t_ignore. This refers to a function within the binding.
The general rules governing Parasolid names in the C# interface are given in Section 12.3, “Parasolid types and names in C#”. There are some identifiers that do not follow these rules exactly, however; this section identifies these special cases.
Since names of identifiers cannot start with a number in C#, the leading digit is replaced by a word of the same meaning. For example:
Note that the “1” in “PK.ATTDEF.class_t.zero1_c” remains a digit; it is only the leading digit in any such name that must be changed.
A leading “@“ is added to the reserved word. For example:
The following reserved words (in C#) are used in the C interface in this way:
char
,
class
,
double
,
false
,
int
,
null
,
string
,
true
,
is
and
goto
.
As mentioned in Section 12.3.7, “Values of Parasolid token types”, there are some token values where the Parasolid name in C does not include the corresponding token-type name (up to the “_t”). In these cases, the C# name must
always include the corresponding
enum
type. The most common cases of these are listed below:
In addition, the following table lists the remaining special cases:
<<< Using Reports | Chapters | Introduction To Basic Concepts In Parasolid >>> |