I am trying to get a callback working in LabVIEW using the PostLVUserEvent. I have it working great using an integer but am having an issue with strings. I have 2 versions that I am working with. The first is the Test LV Callback2.vi. This registers and fires the event all in the same function. This is working and I get the string from the dll back into LabVIEW. The second example is Test LV Callback.vi. This separates things into 2 functions. 1 function to register the LV event. Then a second function to fire the event. This works fine for the integer, but the string it does not. I do not get an event inside LabVIEW. I have tried many different ways and debugging techniques and have not been able to figure out why this is not working. Does anyone have some inisght into what is going on here and some things I can try.
I have attached the code (LV version 2021) The VIs are saved as 2021 but I am using this in LV 2024. For ease of viewing below is the code:
header file:
#pragma once
#include "extcode.h"
// Function prototypes
extern "C" __declspec(dllexport) void RegisterIntCallback(LVUserEventRef* eventRef);
extern "C" __declspec(dllexport) void RegisterStringCallback(LVUserEventRef* eventRef);
extern "C" __declspec(dllexport) void FireIntCallback(); // No parameter
extern "C" __declspec(dllexport) void FireStringCallback(); // No parameter
extern "C" __declspec(dllexport) void RegisterAndFireStringCallback(LVUserEventRef* eventRef);
C++ code
#include "pch.h"
#include "LVCallbackTest.h"
#include "extcode.h"
#include <cstdlib> // For rand()
#include <ctime> // For time()
static LVUserEventRef intEventRef = NULL;
static LVUserEventRef stringEventRef = NULL;
extern "C" __declspec(dllexport) void RegisterIntCallback(LVUserEventRef* eventRef) {
intEventRef = *eventRef;
}
extern "C" __declspec(dllexport) void RegisterStringCallback(LVUserEventRef* eventRef) {
if (eventRef != nullptr) {
stringEventRef = *eventRef; // Dereference and store the value
}
else {
stringEventRef = NULL; // Handle null pointer input
}
}
extern "C" __declspec(dllexport) void FireIntCallback() {
if (intEventRef != NULL) {
std::srand(static_cast<unsigned int>(std::time(0))); // Seed the random number generator
int randomValue = std::rand(); // Generate a random number
PostLVUserEvent(intEventRef, &randomValue);
}
}
extern "C" __declspec(dllexport) void FireStringCallback() {
if (stringEventRef != NULL) {
// Create a LabVIEW string handle
LStrHandle lvStringHandle = (LStrHandle)DSNewHandle(sizeof(int32) + strlen("Hello from the DLL!") * sizeof(uChar));
if (lvStringHandle != NULL) {
// Set the length of the string
LStrLen(*lvStringHandle) = strlen("Hello from the DLL!");
// Copy the string into the handle
memcpy(LStrBuf(*lvStringHandle), "Hello from the DLL!", strlen("Hello from the DLL!"));
// Post the event
PostLVUserEvent(stringEventRef, (void*)&lvStringHandle);
// Dispose of the handle
DSDisposeHandle(lvStringHandle);
}
}
}
extern "C" __declspec(dllexport) void RegisterAndFireStringCallback(LVUserEventRef* eventRef) {
// Register the event
LVUserEventRef stringEventRef = *eventRef;
// Create a LabVIEW string handle
LStrHandle lvStringHandle = (LStrHandle)DSNewHandle(sizeof(int32) + strlen("Hello from the DLL!") * sizeof(uChar));
if (lvStringHandle != NULL) {
// Set the length of the string
LStrLen(*lvStringHandle) = strlen("Hello from the DLL!");
// Copy the string into the handle
memcpy(LStrBuf(*lvStringHandle), "Hello from the DLL!", strlen("Hello from the DLL!"));
// Post the event
PostLVUserEvent(stringEventRef, (void *)&lvStringHandle);
// Dispose of the handle
DSDisposeHandle(lvStringHandle);
}
}
Brad Remenak
Certified LabVIEW Architect