forked from ni/grpc-labview
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlv_interop.h
More file actions
178 lines (151 loc) · 6.45 KB
/
lv_interop.h
File metadata and controls
178 lines (151 loc) · 6.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
//---------------------------------------------------------------------
//---------------------------------------------------------------------
#pragma once
//---------------------------------------------------------------------
//---------------------------------------------------------------------
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
#endif
//---------------------------------------------------------------------
//---------------------------------------------------------------------
#include <string>
#include <string_view>
#include <memory>
#include <pointer_manager.h>
//---------------------------------------------------------------------
//---------------------------------------------------------------------
#ifdef _WIN32
#define LIBRARY_EXPORT extern "C" __declspec(dllexport)
#else
#define LIBRARY_EXPORT extern "C" __attribute__((visibility("default")))
#endif
namespace grpc_labview
{
class gRPCid;
extern PointerManager<gRPCid> gPointerManager;
//---------------------------------------------------------------------
// LabVIEW gRPC definitions
//---------------------------------------------------------------------
class gRPCid
{
public:
/// NOTE: It is important that the CastTo method never be made virtual and never access any member variables.
/// This code is expected to work: ((gRPCid*)nullptr)->CastTo<gRPCid>();
template <typename T>
std::shared_ptr<T> CastTo()
{
return gPointerManager.TryCastTo<T>(this);
}
virtual ~gRPCid() { }
protected:
gRPCid() { }
};
int AlignClusterOffset(int clusterOffset, int alignmentRequirement);
// Provides type code for use with NumericArrayResize function for various sizes of data types.
int32_t GetTypeCodeForSize(int byteSize);
//---------------------------------------------------------------------
// LabVIEW definitions
//---------------------------------------------------------------------
typedef int32_t MagicCookie;
typedef MagicCookie LVRefNum;
typedef MagicCookie LVUserEventRef;
typedef int32_t(*CleanupProcPtr)(gRPCid* id);
typedef uint8_t LVBoolean;
static const LVBoolean LVTrue = 1;
static const LVBoolean LVFalse = 0;
struct LStr {
int32_t cnt; /* number of bytes that follow */
char str[1]; /* cnt bytes */
};
using LStrPtr = LStr*;
using LStrHandle = LStr**;
struct LV1DArray {
int32_t cnt; /* number of T elements that follow */
int8_t rawBytes[1]; /* (cnt * sizeof(T)) bytes */
template<typename T>
T* bytes()
{
static_assert(!std::is_class<T>::value, "T must not be a struct/class type.");
return (T*)(bytes(0, sizeof(T)));
}
template<typename T>
T* bytes(int byteOffset)
{
static_assert(!std::is_class<T>::value, "T must not be a struct/class type.");
return (T*)(bytes(byteOffset, sizeof(T)));
}
void* bytes(int byteOffset, int byteAlignment)
{
return (void*)(rawBytes + AlignClusterOffset(4, byteAlignment) - 4 + byteOffset);
}
};
using LV1DArrayPtr = LV1DArray*;
using LV1DArrayHandle = LV1DArray**;
struct LV2DArray {
int32_t dimensionSizes[2]; /* number of T elements for each dimension */
int8_t rawBytes[1]; /* (firstDimensionSize * secondDimensionSize * sizeof(T)) bytes */
// The start of 2D array data is always aligned and does not require padding.
template<typename T>
T* bytes()
{
static_assert(!std::is_class<T>::value, "T must not be a struct/class type.");
static_assert(sizeof(T) <= 8, "Need to revisit logic if we ever have element size larger than 8 bytes.");
return (T*)(rawBytes);
}
};
using LV2DArrayPtr = LV2DArray*;
using LV2DArrayHandle = LV2DArray**;
//---------------------------------------------------------------------
//---------------------------------------------------------------------
#ifdef _PS_4
#pragma pack (push, 1)
#endif
struct AnyCluster
{
LStrHandle TypeUrl;
LV1DArrayHandle Bytes;
};
#ifdef _PS_4
#pragma pack (pop)
#endif
// Defines cleanup modes which are used with RTSetCleanupProc
enum class CleanupProcMode
{
// Value passed to the RTSetCleanupProc to remove a cleanup proc for the VI.
CleanOnRemove = 0,
// Value passed to the RTSetCleanupProc to register a cleanup proc that is called when
// the LV application context exits.
CleanOnExit = 1,
// Value passed to the RTSetCleanUpProc to register a cleanup proc for a VI that is called
// when the VI state changes to Idle.
CleanOnIdle = 2,
// Value passed to the RTSetCleanUpProc to register a cleanup proc for a VI that is called
// when the VI state changes to Idle after a reset.
CleanAfterReset = 3
};
//---------------------------------------------------------------------
//---------------------------------------------------------------------
void SetLVRTModulePath(const std::string& modulePath);
void InitCallbacks();
// Protobuf package/message/field names are ASCII strings.
void SetLVAsciiString(LStrHandle* lvString, std::string_view str);
std::string GetLVAsciiString(LStrHandle lvString);
// Protobuf `bytes` fields are binary data.
void SetLVBytes(LStrHandle* lvString, std::string_view str);
std::string GetLVBytes(LStrHandle lvString);
// Protobuf `string` fields are UTF-8 strings.
void SetLVString(LStrHandle* lvString, std::string_view str);
std::string GetLVString(LStrHandle lvString);
int NumericArrayResize(int32_t typeCode, int32_t numDims, void* handle, size_t size);
int PostUserEvent(LVUserEventRef ref, void* data);
unsigned char** DSNewHandle(size_t n);
int DSSetHandleSize(void* h, size_t n);
long DSDisposeHandle(void* h);
int SignalOccurrence(MagicCookie occurrence);
int32_t RegisterCleanupProc(CleanupProcPtr cleanUpProc, grpc_labview::gRPCid* id, CleanupProcMode cleanupCondition = CleanupProcMode::CleanOnIdle);
int32_t DeregisterCleanupProc(CleanupProcPtr cleanUpProc, grpc_labview::gRPCid* id);
int ConvertSystemStringToUTF8(LStrHandle stringIn, LStrHandle *stringOut);
int ConvertUTF8StringToSystem(LStrHandle stringIn, LStrHandle *stringOut);
}