At first I am new on both tensorflow and python to start with.
I have a python code that contains a TFlearn DNN network. I need to convert that code to C++ to later on convert it into a library to be used in mobile application development.
I read about the C++ API for tensorflow (of which documentations are real vague and not clear). so I took the code line by line to try converting it.
The first step was loading the saved model that was was previously trained and saved in python (I don't need training to be done in c++ so just loading the tflearn model is enough)
The python code to save the file was as follows:
network = input_data(shape=[None, 100, 100, 1], name='input')
network = conv_2d(network, 32, 5, activation='relu')
network = avg_pool_2d(network, 2)
network = conv_2d(network, 64, 5, activation='relu')
network = avg_pool_2d(network, 2)
network = fully_connected(network, 128, activation='relu')
network = fully_connected(network, 64, activation='relu')
network = fully_connected(network, 2, activation='softmax',restore=False)
network = regression(network, optimizer='adam', learning_rate=0.0001,
loss='categorical_crossentropy', name='target')
model = tflearn.DNN(network, tensorboard_verbose=0)
model.fit(X, y.toarray(), n_epoch=3, validation_set=0.1, shuffle=True,
show_metric=True, batch_size=32, snapshot_step=100,
snapshot_epoch=False, run_id='model_finetuning')
model.save('model/my_model.tflearn')
To load the model python code was:
network = input_data(shape=[None, 100, 100, 1], name='input')
network = conv_2d(network, 32, 5, activation='relu')
network = avg_pool_2d(network, 2)
network = conv_2d(network, 64, 5, activation='relu')
network = avg_pool_2d(network, 2)
network = fully_connected(network, 128, activation='relu')
network = fully_connected(network, 64, activation='relu')
network = fully_connected(network, 2, activation='softmax')
network = regression(network, optimizer='adam', learning_rate=0.001,
loss='categorical_crossentropy', name='target')
model = tflearn.DNN(network, tensorboard_verbose=0)
model.load('model/my_model.tflearn')
and this code worked like a charm in python, yet the model save file was actually 4 files inside the model folder as follows:
model
|------------checkpoint
|------------my_model.tflearn.data-00000-of-00001
|------------my_model.tflearn.index
|------------my_model.tflearn.meta
now I come to the c++ part of it. After a lot of research I came up with the following code:
#include "tensorflow/core/public/session.h"
#include "tensorflow/core/platform/env.h"
#include <iostream>
using namespace tensorflow;
using namespace std;
int main()
{
Session* session;
Status status = NewSession(SessionOptions(), &session);
if (!status.ok())
{
cerr << status.ToString() << "\n";
return 1;
}
else
{
cout << "Session created successfully" << endl;
}
tensorflow::Tensor input_tensor(tensorflow::DT_FLOAT, tensorflow::TensorShape({1,100,100,1}));
GraphDef graph_def;
status = ReadBinaryProto(Env::Default(), "/home/user/PycharmProjects/untitled/model/my_model.tflearn", &graph_def);
if (!status.ok())
{
cerr << status.ToString() << "\n";
return 1;
}
else
{
cout << "Read Model File" << endl;
}
return 0;
}
And now for my questions, the code compile correctly (with no faults) using the bazel build (as described in the "Short" explanation of tensorflow C++ API. but when I tried to run it the model file is not found.
Is what I did in c++ correct? Is this the correct way to load the saved model (which I don't know why 4 files are generated during save)? or is there another approach to do it?
Is there any "Full and descent" manual for the tensorflow c++ API?
If you just want to load an already trained model, a c++ loader already exists. Directly on tensorflow look here and here
Patwie also got a really good example for loading a saved model Code from Patwie.
tensorflow::Status LoadModel(tensorflow::Session *sess, std::string graph_fn, std::string checkpoint_fn = "") {
tensorflow::Status status;
// Read in the protobuf graph we exported
tensorflow::MetaGraphDef graph_def;
status = ReadBinaryProto(tensorflow::Env::Default(), graph_fn, &graph_def);
if (status != tensorflow::Status::OK())
return status;
// create the graph in the current session
status = sess->Create(graph_def.graph_def());
if (status != tensorflow::Status::OK())
return status;
// restore model from checkpoint, iff checkpoint is given
if (checkpoint_fn != "") {
const std::string restore_op_name = graph_def.saver_def().restore_op_name();
const std::string filename_tensor_name = graph_def.saver_def().filename_tensor_name();
tensorflow::Tensor filename_tensor(tensorflow::DT_STRING, tensorflow::TensorShape());
filename_tensor.scalar<std::string>()() = checkpoint_fn;
tensor_dict feed_dict = {{filename_tensor_name, filename_tensor}};
status = sess->Run(feed_dict,
{},
{restore_op_name},
nullptr);
if (status != tensorflow::Status::OK())
return status;
} else {
// virtual Status Run(const std::vector<std::pair<string, Tensor> >& inputs,
// const std::vector<string>& output_tensor_names,
// const std::vector<string>& target_node_names,
// std::vector<Tensor>* outputs) = 0;
status = sess->Run({}, {}, {"init"}, nullptr);
if (status != tensorflow::Status::OK())
return status;
}
Unfortunatly there isn't a "full and descent" manual for tensorflow c++ API yet (AFAIK)
I wrote the steps how to save a TFLearn checkpoint correctly:
...
model = tflearn.DNN(network)
class MonitorCallback(tflearn.callbacks.Callback):
# Create an other session to clone the model and avoid effecting the training process
with tf.Session() as second_sess:
# Clone the current model
model2 = model
# Delete the training ops
del tf.get_collection_ref(tf.GraphKeys.TRAIN_OPS)[:]
# Save the checkpoint
model2.save('checkpoint_'+str(training_state.step)+".ckpt")
# Write a text protobuf to have a human-readable form of the model
tf.train.write_graph(second_sess.graph_def, '.', 'checkpoint_'+str(training_state.step)+".pbtxt", as_text = True)
return
mycb = MonitorCallback()
model.fit({'input': X}, {'target': Y}, n_epoch=500, run_id="mymodel", callbacks=mycb)
...
After you have the checkpoint, you can load in C++:
https://github.com/kecsap/tensorflow_cpp_packaging#load-a-checkpoint-in-c
...and you it for inference:
https://github.com/kecsap/tensorflow_cpp_packaging#inference-in-c
You can also find example code for C and how to freeze a model then load in C++.
Okay, so we have an extension that is written in C for Tcl 8.4 using LabWindows. After upgrading to Tcl 8.6 calling any procedures that were produced by the dll causes wish to crash without producing a useful error code. This happens from both a script and if I manually load the library and call a procedure from the wish shell.
Now, this only happens when I install Tcl 8.6 over 8.4. If I do a fresh install of 8.6 it says the the dll is missing a dependent library. So, I used dependency walker to see that the dll is dependent on tcl84.dll whereas my extensions made with Visual Studio(VS) and even other old LabWindows projects also don't have this listed as a dependency.
Any project that doesn't have tcl84.dll listed as a dependency, as you might expect, works fine on Tcl 8.6, both a fresh install and being installed over 8.4.
So does anyone have any idea why the extension is dependent on tcl84.dll when others are not?
Here's the source:
SI.c only up to the init method(entire file is too large)
#include <analysis.h>
#include "toolbox.h"
#include <utility.h>
#include <ansi_c.h>
#include "SI.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
int DLLEXPORT Si_Init(Tcl_Interp *interp) {
////////////////////////////////////////////////////////////////////////////////////////////////////
if (Tcl_InitStubs(interp, "8.4", 0) == NULL) {
return TCL_ERROR;
}
//TCL Exported Functions
Tcl_CreateObjCommand(interp, "LoadWfm", (Tcl_ObjCmdProc*)LoadWfm,(ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
Tcl_CreateObjCommand(interp, "SaveWfm", (Tcl_ObjCmdProc*)SaveWfm,(ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
Tcl_CreateObjCommand(interp, "Step2SParam", (Tcl_ObjCmdProc*)Step2SParam,(ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
Tcl_CreateObjCommand(interp, "Step2Eye", (Tcl_ObjCmdProc*)Step2Eye,(ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
Tcl_PkgProvide(interp, "SI", "1.0");
return TCL_OK;
}
SI.h
//Exported Functions
int DLLEXPORT Si_Init(Tcl_Interp *interp);
int DLLEXPORT LoadWfm(ClientData clientData, Tcl_Interp *interp,int objc, Tcl_Obj *CONST objv[]);
int DLLEXPORT SaveWfm(ClientData clientData, Tcl_Interp *interp,int objc, Tcl_Obj *CONST objv[]);
int DLLEXPORT Step2SParam(ClientData clientData, Tcl_Interp *interp,int objc, Tcl_Obj *CONST objv[]);
int DLLEXPORT Step2Eye(ClientData clientData, Tcl_Interp *interp,int objc, Tcl_Obj *CONST objv[]);
//Local Functions
int StepToSParam (double *vin, double *vout, double dt, int N, double **S_real_out, double **S_imag_out, double *S_f0_out, double *S_df_out, int *S_N_out);
double RisetimeToBandwidth_20_80(double x);
double RisetimeToBandwidth_10_90(double x);
int GaussianFilter(double *Waveform, int Samples, double SampleTime, int BitPoints, double Bandwidth);
int NormalizeAmplitude (double *Waveform, int Samples, double Vpp);
int FunctionGenerator(int BitPattern[], int PatternLength, int PatternCycles, double Freq, double Vpp, double Risetime,
int Risetime2080, double dt, int *Samples, double **Waveform);
int ZeroPad (double **wfm, int N, int NewN);
int ParZ(double Z1_Re, double Z1_Im, double Z2_Re, double Z2_Im, double *ZT_Re, double *ZT_Im);
int ReflCoef(double Z1_Re, double Z1_Im, double Z2_Re, double Z2_Im, double *ZRefl_Re, double *ZRefl_Im);
int SixCompEq(double f, double Zcab, double Rld, double R1, double C, double R3, double L, double *T_Re, double *T_Im);
int FourCompEq(double f, double Zcab, double Rld, double R1, double C, double R3, double L, double *T_Re, double *T_Im);
int ApplyEq(int NumComponents, int EQ_N, double df, double Zcab, double Rld, double R1,
double C, double R3, double L, double *T_Re, double *T_Im);
int SimulateEye (double *in, double *out, int N, double dt,
char *Pattern_String, int Pattern_Inverted, int Pattern_Cycles, double Pattern_BitRate,
double Pattern_Risetime, int Pattern_2080, double Pattern_Amplitude,
int EQ_NumComponents, double EQ_Zcab, double EQ_Rld, double EQ_R1, double EQ_C, double EQ_R3, double EQ_L,
double **Eye_Pattern, double *Eye_dt, int *Eye_N);
int FindPatternStartIndex(double *EyeWfm, double Eye_dt, int Eye_N, double Pattern_Bitrate, int Pattern_Bits, int Pattern_Cycles);
And if anyone is familiar with LabWindows, here's the project setting files:
SI.prj
[Project Header]
Version = 800
Pathname = "/c/CVS_CHECKOUT/MHTS/SI/SI.prj"
CVI Dir = "/c/program files/national instruments/cvi80"
IVI Standard Root Dir = "/C/Program Files/IVI"
VXIplug&play Framework Dir = "/C/VXIPNP/winnt"
Number of Files = 4
Target Type = "Dynamic Link Library"
Flags = 16
[File 0001]
File Type = "Include"
Res Id = 1
Path Is Rel = True
Path Rel To = "Project"
Path Rel Path = "../Include/molex_tcl.h"
Path = "/c/CVS_CHECKOUT/MHTS/Include/molex_tcl.h"
Exclude = False
Project Flags = 0
Folder = "Included Files"
[File 0002]
File Type = "CSource"
Res Id = 2
Path Is Rel = True
Path Rel To = "Project"
Path Rel Path = "SI.c"
Path = "/c/CVS_CHECKOUT/MHTS/SI/SI.c"
Exclude = False
Compile Into Object File = False
Project Flags = 0
Folder = "Source Files"
[File 0003]
File Type = "Include"
Res Id = 3
Path Is Rel = True
Path Rel To = "Project"
Path Rel Path = "SI.h"
Path = "/c/CVS_CHECKOUT/MHTS/SI/SI.h"
Exclude = False
Project Flags = 0
Folder = "Source Files"
[File 0004]
File Type = "Library"
Res Id = 4
Path Is Rel = True
Path Rel To = "Project"
Path Rel Path = "../Include/tclDecls.lib"
Path = "/c/CVS_CHECKOUT/MHTS/Include/tclDecls.lib"
Exclude = False
Project Flags = 0
Folder = "Included Files"
[Folders]
Include Files Folder Not Added Yet = True
User Interface Files Folder Not Added Yet = True
Instrument Files Folder Not Added Yet = True
Folder 0 = "Source Files"
Folder 1 = "Included Files"
[Compiler Options]
Default Calling Convention = "cdecl"
Require Prototypes = True
Require Return Values = True
Enable Pointer Mismatch Warning = False
Enable Unreachable Code Warning = False
Enable Unreferenced Identifiers Warning = False
Enable Assignment In Conditional Warning = False
O Option Compatible With 5.0 = False
Uninitialized Locals Compile Warning = "Conservative"
[Run Options]
Stack Size = 250000
Image Base Address = 4194304
[Compiler Defines]
Compiler Defines = "/DWIN32_LEAN_AND_MEAN /D_MSC_VER=1200 /D_WINDEF_"
[Include Paths]
Include Path 1 Is Rel = False
Include Path 1 = "/c/CVS_CHECKOUT/MHTS/Include"
Include Path 2 Is Rel = False
Include Path 2 = "/c/Tcl/include"
[Create Executable]
Executable File_Debug Is Rel = True
Executable File_Debug Rel To = "Project"
Executable File_Debug Rel Path = "SI_dbg.dll"
Executable File_Debug = "/c/CVS_CHECKOUT/MHTS/SI/SI_dbg.dll"
Executable File_Release Is Rel = True
Executable File_Release Rel To = "Project"
Executable File_Release Rel Path = "SI.dll"
Executable File_Release = "/c/CVS_CHECKOUT/MHTS/SI/SI.dll"
Icon File Is Rel = False
Icon File = ""
Application Title = ""
DLL Exports = "Symbols Marked As Export"
DLL Import Library Choice = "Gen Lib For Current Mode"
Use IVI Subdirectories for Import Libraries = False
Use VXIPNP Subdirectories for Import Libraries = False
Use Dflt Import Lib Base Name = True
Where to Copy DLL = "Do not copy"
Add Type Lib To DLL = False
Include Type Lib Help Links = False
Type Lib FP File Is Rel = False
Type Lib FP File = ""
Type Lib Guid = ""
Runtime Support = "Full Runtime Support"
Instrument Driver Support Only = False
Embed Project .UIRs = False
Generate Map File = False
[External Compiler Support]
UIR Callbacks File Option = 0
Using LoadExternalModule = False
Create Project Symbols File = True
UIR Callbacks Obj File Is Rel = False
UIR Callbacks Obj File = ""
Project Symbols H File Is Rel = False
Project Symbols H File = ""
Project Symbols Obj File Is Rel = False
Project Symbols Obj File = ""
[ActiveX Server Options]
Specification File Is Rel = False
Specification File = ""
Source File Is Rel = False
Source File = ""
Include File Is Rel = False
Include File = ""
IDL File Is Rel = False
IDL File = ""
Register ActiveX Server = False
[tpcSection]
tpcEnabled = 0
tpcOverrideEnvironment = 0
SI.cws
[Workspace Header]
Version = 800
Pathname = "/c/CVS_CHECKOUT/MHTS/SI/SI.cws"
CVI Dir = "/c/program files/national instruments/cvi80"
IVI Standard Root Dir = "/C/Program Files/IVI"
VXIplug&play Framework Dir = "/C/VXIPNP/winnt"
Number of Projects = 1
Active Project = 1
Project 0001 = "SI.prj"
Drag Bar Left = 323
Window Top = 137
Window Left = 1190
Window Bottom = 1041
Window Right = 2278
Maximized = True
Maximized Children = True
Max Number Of Errors = 20
Track Include File Dependencies = True
Prompt For Missing Includes = True
Stop On First Error File = False
Bring Up Err Win For Warnings = True
Show Build Dialog = False
Save Changes Before Running = "Always"
Hide Windows = False
Global Hot Key = False
Break At First Statement = False
Sort Type = "File Name"
Number of Opened Files = 3
Window Confinement Region Enabled = True
MainColumnWidth = 304
FileDateColumnWidth = 70
FileSizeColumnWidth = 70
StatusColumnWidth = 70
[Project Header 0001]
Version = 800
Don't Update DistKit = False
Platform Code = 4
Build Configuration = "Release"
Warn User If Debugging Release = 1
Batch Build Release = False
Batch Build Debug = False
Force Rebuild = False
[File 0001]
Path = "/c/CVS_CHECKOUT/MHTS/SI/SI.c"
File Type = "CSource"
Disk Date = 3288546022
In Projects = "1,"
Window Top = 163
Window Left = 78
Window Z-Order = 1
Source Window State = "1,191,191,191,54,55,55,0,0,116,0,25,0,25,0,51,150,0,192,6,349,676,1,0,"
Breakpoint 0001 = "166,0,enabled,"
Breakpoint 0002 = "195,0,enabled,"
[File 0002]
Path = "/c/CVS_CHECKOUT/MHTS/SI/SI.h"
File Type = "Include"
Disk Date = 3262700601
In Projects = "1,"
Window Top = 30
Window Left = 6
Window Z-Order = 2
Source Window State = "1,27,28,27,0,0,0,0,0,80,0,28,0,28,0,25,0,45,27,130,349,676,1,0,"
[File 0003]
Path = "/c/CVS_CHECKOUT/MHTS/Include/molex_tcl.h"
File Type = "Include"
Disk Date = 3275700706
In Projects = "1,"
Window Top = 30
Window Left = 6
Window Z-Order = 3
Source Window State = "1,15,16,16,86,159,159,0,0,80,0,0,0,0,0,25,0,0,35,33,349,676,1,0,"
[File 0004]
Path = "/c/CVS_CHECKOUT/MHTS/Include/tclDecls.lib"
File Type = "Library"
Disk Date = 3262622625
In Projects = "1,"
[Build Options 0001]
Generate Browse Info = True
Enable Uninitialized Locals Runtime Warning = True
Debugging Level = "Standard"
Break On Library Errors = False
Break On First Chance Exceptions = False
Execution Target Address = "Local desktop computer"
Execution Target Port = 0
Execution Target Type = 0
[SCC Options 0001]
Use global settings = True
SCC Provider = ""
SCC Project = ""
Local Path = ""
Auxiliary Path = ""
Perform Same Action For .h File As For .uir File = "Ask"
Username = ""
Comment = ""
Use Default Username = False
Use Default Comment = False
Suppress CVI Error Messages = False
[DLL Debugging Support 0001]
External Process Path = "/c/Tcl/bin/wish.exe"
[DLLs Used By Executable 0001]
DLL 0001 = "/C/Tcl/bin/tcl84.dll"
[Command Line Args 0001]
Command Line Args = ""
The most promising possibility looks to be this line in the .cws file:
[DLLs Used By Executable 0001]
DLL 0001 = "/c/Tcl/bin/tcl84.dll"
but here is the .cws file from another LabWindows project:
OK.cws
[Workspace Header]
Version = 800
Pathname = "/c/CVS_CHECKOUT/MHTS/OK/OK.cws"
CVI Dir = "/c/program files/national instruments/cvi80"
IVI Standard Root Dir = "/C/Program Files/IVI"
VXIplug&play Framework Dir = "/C/VXIPNP/winnt"
Number of Projects = 1
Active Project = 1
Project 0001 = "OK.prj"
Drag Bar Left = 181
Window Top = 101
Window Left = 1404
Window Bottom = 974
Window Right = 2676
Maximized = True
Maximized Children = True
Max Number Of Errors = 20
Track Include File Dependencies = True
Prompt For Missing Includes = True
Stop On First Error File = False
Bring Up Err Win For Warnings = True
Show Build Dialog = False
Save Changes Before Running = "Always"
Hide Windows = False
Global Hot Key = False
Break At First Statement = False
Sort Type = "File Name"
Number of Opened Files = 1
Window Confinement Region Enabled = True
MainColumnWidth = 162
FileDateColumnWidth = 70
FileSizeColumnWidth = 70
StatusColumnWidth = 70
[Project Header 0001]
Version = 800
Don't Update DistKit = False
Platform Code = 4
Build Configuration = "Debug"
Warn User If Debugging Release = 1
Batch Build Release = False
Batch Build Debug = False
Force Rebuild = False
[File 0001]
Path = "/c/CVS_CHECKOUT/MHTS/OK/OK.c"
File Type = "CSource"
Disk Date = 3291811857
In Projects = "1,"
Window Top = 59
Window Left = 80
Window Z-Order = 1
Source Window State = "1,503,503,503,14,32,32,0,0,133,0,37,0,51,29,59,478,0,514,78,663,815,1,0,"
[File 0002]
Path = "/c/CVS_CHECKOUT/MHTS/Include/molex_tcl.h"
File Type = "Include"
Disk Date = 3275700706
In Projects = "1,"
Window Top = 48
Window Left = 18
Source Window State = "1,8,9,8,0,0,0,0,0,0,0,0,0,0,0,0,1,0,8,12,461,988,1,0,"
[File 0003]
Path = "/c/CVS_CHECKOUT/MHTS/OK/OK.h"
File Type = "Include"
Disk Date = 3291811853
In Projects = "1,"
Window Top = 614
Window Left = 299
Source Window State = "1,4,4,4,17,21,17,0,0,0,0,16,0,16,0,0,0,0,15,17,278,676,1,0,"
[File 0004]
Path = "/c/Program Files/Opal Kelly/FrontPanel/API/okFrontPanelDLL.h"
File Type = "Include"
Disk Date = 3268500132
In Projects = "1,"
Window Top = 130
Window Left = 11
Source Window State = "1,218,218,218,51,68,51,0,3,0,0,0,0,0,0,0,197,0,218,68,476,725,1,0,"
[File 0005]
Path = "/c/CVS_CHECKOUT/MHTS/Include/tclDecls.lib"
File Type = "Library"
Disk Date = 3262622625
In Projects = "1,"
[Build Options 0001]
Generate Browse Info = True
Enable Uninitialized Locals Runtime Warning = True
Debugging Level = "Standard"
Break On Library Errors = False
Break On First Chance Exceptions = False
Execution Target Address = "Local desktop computer"
Execution Target Port = 0
Execution Target Type = 0
[SCC Options 0001]
Use global settings = True
SCC Provider = ""
SCC Project = ""
Local Path = ""
Auxiliary Path = ""
Perform Same Action For .h File As For .uir File = "Ask"
Username = ""
Comment = ""
Use Default Username = False
Use Default Comment = False
Suppress CVI Error Messages = False
[DLL Debugging Support 0001]
External Process Path = "/c/Tcl/bin/wish.exe"
[DLLs Used By Executable 0001]
DLL 0001 = "/c/Tcl/bin/tcl84.dll"
[Command Line Args 0001]
Command Line Args = ""
...it has the same line, yet this project works properly after updating to Tcl 8.6.
UPDATE 5/13/2013 9:00 AM - From what I can tell from all the answers and comments so far is that it definitely has to have something to do with some idiosyncratic in the LabWindows build. So, I'll be getting a copy of it hopefully by the end of the work day today and I'll update my question with the results.
UPDATE 5/13/2013 2:13 PM - Okay so I got LabWindows and first tried deleting the line in the .cws file and re-compiling. The IDE simply re-generates the line before compiling and ends up with the same result. So, I then created a new project from scratch and brought over only the .c and .h files. I set up all the includes and project settings manually and when I got a successful build I looked at the .cws file and the line had been auto-generated again producing the same results. Therefore, there must some function call or reference in the .c or .h file that is referencing tcl84.dll. Any additional insights would be very much appreciated.
You properly use the Tcl STUBS support with your call to Tcl_InitStubs() but throw the benefits out of the window by linking with Tcl84.dll.
If you use Stubs, you only need to link with the stubs version of the oldest DLL you need. In this case the lib called 'tclstub84.lib'. This static library takes care of the magic needed to allow a Tcl 8.6 to load a 8.4 library without recompiling.
You probably need the TCL_USE_STUBS compiler define too, to make it work properly.
See http://tcl.activestate.com/doc/howto/stubs.html for further details how to properly enable STUBS support for your library.
Deep within SI.cws you have
[DLLs Used By Executable 0001]
DLL 0001 = "/C/Tcl/bin/tcl84.dll"
which looks as though it's where the dependency comes from.
That's the easy bit. I'm unfamiliar LabWindows and VisualStudio, so I have no informed idea what you should do to resolve this.
Mind you, changing the above line to specify tcl86.dll looks tempting :-)