Extern() with managed types?


Recommended Posts

Hi guys,

Most of the documentation and forum on "extern" has usually discussed .dll's the the user has source code access to, but I want to call one of the .NET .dll's (or eventually a system .dll).

I want to be able to speak a string from DAQFactory. .NET conveniently has the System.Speech.Speak(string text) method. I'm more familiar accessing it with C#, but I'll link you the documentation and provide the C++ declaration here:

public:void Speak( String^ textToSpeak)

Much to my chagrin, the textToSpeak is a managed type string, so I was wondering if you guys had recommendations on the proper way to define this within DAQFactory (or if this was even defineable at all). My first crack at it was simply:

extern("C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\System.Speech.dll", "void System.Speak(string textToSpeak)","SpeakString", "stdcall","SpeakString(string strToSpeak)")

SpeakString("Ha Ha Ha")

which didn't work, and I tried a variety of char and char* and const char* types and I haven't had any luck. Do you guys have any recommendations on what direction I should be headed with this?

Link to comment
Share on other sites

First, why don't you just use the built in TAPI text to speech features of DAQFactory?

Next, DAQFactory isn't a managed app, so can't call managed dll's directly. The only way for this to work, and I can't guarantee it even then, is to create a wrapper DLL that exposes a function without mangling (inside an extern "C") that takes a const char * and then converts it to your managed string and calls the desired function.

This actually applies to calling any library that doesn't expose its DLL functions as simple C function calls.

Link to comment
Share on other sites

Sorry - wasn't aware of the TAPI functionality, so I did some reading. Can I use TAPI to speak directly to my local soundcard? I guess just use the GetDeviceList function and see if my soundcard is one of the supported devices, or is it exclusive to modems? Sorry for coming right out and asking, but I don't want to waste time digging a needless hole if I should be writing a wrapper file.


Link to comment
Share on other sites

Alright, so playing around a bit, I typed up the following:

local string TapiDevs = TAPI.GetDeviceList()


delay(1)? "about to speak to " + TapiDevs[0] + ", " + TapiDevs[1] + ", " + TapiDevs[2] + ", " + TapiDevs[3] + ", " + TapiDevs[4] //+ ", " + TapiDevs[5] //+ ", " + TapiDevs[6]

TAPI.Speak("HA HA HA")

The list of devices in TapiDevs are: RAS PPPoE Line0000, RAS VPN Line 0, WAN Miniport (L2TP), IPCONF LINE

No matter which device string I use to call TAPI.Init(), I always end up with the following error:

03/29/10 14:07:39.030

T1002: TAPI error: not currently in call. Unable to perform action.

Any recommendations? Thanks

Link to comment
Share on other sites

First, none of those are your sound card, so you'll need to find tapi settings.

Second, you actually have to make some sort of call with tapi.dial(), maybe passing an empty string? I've never actually tried this before, so you may have to experiment more. You also might do a search on the Internet for doing text to speech using TAPI through your sound card from a command line. Then you could use System.ShellExecute() instead.

Link to comment
Share on other sites

Ok, so I guess we've answered "First, why don't you just use the built in TAPI text to speech features of DAQFactory?" If I'm going to execute a batch file, there are easier ways to do it than going through the TAPI rabbit hole. I was originally hoping to use something common amongst either Windows or DAQFactory to keep my code compatible across a few machines running DAQFactory, to minimize hassles in the future when machines are upgraded, etc. when I'm no longer here.

I'll keep digging around, and report back if I find a better solution.

Link to comment
Share on other sites

Okay, so I wrote up a little text to speech program that talks out the first parameter that it gets when called. So in command prompt, I type:

C:\DAQFactory\Speech\Speaker.exe "It will announce this text"

And the computer will say the text. So then I typed in my sequence:

local string stringtosay = chr(34) + "Alert Alert Alert"+ chr(34)

System.ShellExecute("Speech\Speaker.exe", "open", stringtosay, "", "minimize")

And I can't get that part to work right now. I should have to put in the extra quotation marks, right? Otherwise every word will be a separate parameter. Any advice?

Link to comment
Share on other sites

Probably, but you don't need to use chr(34), and unless you are using objects, you don't want to use local to declare your variable. Try just doing:

System.ShellExecute("Speech\Speaker.exe", "open", '"Alert Alert Alert"', "", "minimize")

DAQFactory allows both single ' and double " to be used for strings, so if you need double quotes in your string, just use single quotes around it all.

Link to comment
Share on other sites

Actually, my program isn't even being started. I put some hooks in it to wait for user input before exiting, and I simply ran:


And it doesn't get started. This one line was put in its own Sequence. I also tried the code above, and got nothing. Weird.

Link to comment
Share on other sites


This topic is now archived and is closed to further replies.