Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
JawnV6
Jul 4, 2004

So hot ...
I have a C program that compiles cleanly on Linux/OSX. I need it to run on Windows. There is some light file i/o and a lot of usage of a COM port.

I am familiar with C#'s COM port handling and so far I'm able to communicate to the device. Before I get into the heavy lifting of duplicating the C program's functionality in C#, is there a lighter path than this? I've spent two nights on skype trying to walk a technician through using this under linux and a rewrite is looking better and better.

Adbot
ADBOT LOVES YOU

JawnV6
Jul 4, 2004

So hot ...

ljw1004 posted:

When I ported C code from linux to windows, I just kept it in C/C++. If it already used FILE* in C, then it was easy to make that work under windows. (However I never did any COM port stuff). I didn't understand from your post why you also want it in C# ?

Thanks for the reply, apologies for my delay. My thinking was that the higher-level functionality was easier to duplicate than the lower level. The majority of my work is C in embedded platforms. But I'm more comfortable in C# in windows than C, if that makes any sense. It's the choice between figuring out how to duplicate ssize_t and optind or re-writing the functionality I already understand in C#. Worked through some other issues with the vendor and got the Linux version up and running in the factory, but still wasn't able to get through the whole COM sequence. At this point I'm suspecting faulty hardware in the factory since my boards here are working with a much better success rate than they saw.

It's not using FILE*, but I've found some examples of VCP usage in windows C. I've got the cli compiler failing expectedly on it, I'll see if I can get it cleaned up before the factory hits me up tonight.

JawnV6
Jul 4, 2004

So hot ...
I have more serial port weirdness I need to figure out.

Right now in C# I'm using a Timer to poll a serial device. It writes to the port, then does a try{} to catch a timeout on the Read in case the device does not respond.

A different test requires that the PC avoid writing anything to the port for an unknown time. I've found an example on setting up a DataReceived Handler. It seems straightforward to have a button that sets up the handler, turns off the timer, and wait for the device to deliver data.

However, I need the ability to go back to polling. I think I can get away with having the DataReceived handler always attached. It'll check if the timer's active and return without touching the port. Essentially treating the timer's Enable as the differentiator between the two states. Is that going to work? I understand there's some weirdness in the handler as I can't change UI elements directly, I have to throw it through an Invoke delegate. Can I sample the timer's Enable on the other thread without issues? It would be pulled low by a button and re-enabled at the end of the handler if the proper data is received.

JawnV6
Jul 4, 2004

So hot ...
I've completed half of this. The polling portion is working fine. I'm not having issues opening or closing ports?

All of my work so far has been controlling the code on the device itself. It sleeps, wait for a byte to come in from the PC, then replies back with data. For this, I can't control the code on the device. It is speaking to another module, then sends a message to the PC when that procedure is done. While this is happening I can't send anything to the device or electrical demons might burn it all down. I don't want to touch the existing polling loop. I want to set up a handler that scans for the end message and pass control back to the timer when it comes in.

It's not throwing any warnings when I'm reading and modifying the timer enable in the handler thread, so I'm pretty sure there's no issues there. I'm fighting the various flavors of Read to figure out which one's appropriate for the handler to use.

JawnV6
Jul 4, 2004

So hot ...
ReadExisting() kicks back a string. Since there are goofy non-ascii bytes, the string turns into a not-string and despite shoving "pass" in one side, .Contains("pass") won't detect the mangled "\0p\0a\0s\0s". I'm trying to use Read() with a specific byte count into an array and parse that. There's a variety of messages getting passed back and forth, I can't say anything safely, and must detect a particular message.

My favorite sp weirdness is ReadByte() kicking back a int :v:

JawnV6
Jul 4, 2004

So hot ...
ReadByte does not return a byte. It returns an int. An explicit conversion is required, it will not compile without that conversion. I'm confused what TryParse would help here.

That Read() call is what I've been using on the polling side. Apologies that wasn't clear. I can control that message and how many bytes it is, no issues. Now what I'm seeing is that when I'm 'listening in' on the other two devices communicating and checking things inside the handler, sp.BytesToRead is all over the map. Run to run variation, sometimes I get 1 byte when the channel never sends only one byte. It's never a relatively clean blob like reading into a byte buffer.

I might have to do something like your earlier suggestion and just wait a while. I can get control back of the messages after the indeterminate wait for a pass, I might just go back to the polling, block the write when it might be unsafe, and let my existing stuff to snip messages and make sure I'm looking at the right window get it back on track.

Thanks for the help. Pretty sure I can crack this with enough time at this point.

JawnV6
Jul 4, 2004

So hot ...
I have an application deployed that uses HttpWebRequest to send a request to a sever. They're seeing an unexpected error, "Method not found: 'System.Net.HttpWebRequest". It appears to be in every .net version from 1.0 to 4.5. All of the error pages google brings up are dealing with some old Mono version missing this. How does an installation miss out on a chunk like this?

The entire code using this class:
code:
HttpWebRequest hwr = WebRequest.CreateHttp(url);
HttpWebResponse response;
try
{
            response = (HttpWebResponse)hwr.GetResponse();
            Stream receiveStream = response.GetResponseStream();
Not really sure what to do. I need to hit a particular URL with a user-supplied string, check the response and display a Pass/Fail. Is there another method to doing this that's more available?

JawnV6
Jul 4, 2004

So hot ...

Malcolm XML posted:

install http client libraries from nuget and use those https://www.nuget.org/packages/Microsoft.Net.Http

It's unclear to me how grabbing something else in an extra complicated way is going to make that new thing available on a remote computer I have zero control over and is already missing core functionality? Am I missing some bit about how this works?

JawnV6
Jul 4, 2004

So hot ...
I'm not using mono. The only error pages that popped up are in reference to mono. I'm clearly not explaining myself all that well, and I apologize for the tone. I don't want to explain the horrible delivery I'm papering over with "deployed" nor the environment this is running in so it's just X/Ying from here down.

I've tried rewriting it with WebClient instead of HWR, that's probably going to suffice for this round of onion peeling. Cheers!

JawnV6
Jul 4, 2004

So hot ...

ljw1004 posted:

You're imaging the possibility that System.Net.dll is absent on the target machine, and that Microsoft.Net.HttpClient is a wrapper built around it. That's possible but seems unlikely because -- why would it be absent??

I'm looking at a screenshot from a factory floor. They might not have the latest/greatest setup there, but they have enough .NET to put a button on the screen so it hasn't been an issue so far.

I didn't close the single quote because the dialog didn't close the quote. I understand that the actual method isn't present in what I'm saying, that information is unavailable to me as well. I posted the entirety of the code, thinking that the single method call on that object would be enough information.

JawnV6
Jul 4, 2004

So hot ...
I have a reference application in C++ that uses a DLL for a USB device. It needs to integrate with a C# app I'm already building. I wanted to just import the DLL into C#, but I'm hitting errors I haven't seen before and hit my limits on google/SO.

When I try to grab the DLLthrough Reference Manager, the error pops up as "A reference to "dll_name.dll" could not be added. Please make sure the file is accessible, and that it is a valid assembly or COM component." This led me to a SO answer suggesting TlbImp.exe, which gives me

quote:

Microsoft (R) .NET Framework Type Library to Assembly Converter 3.5.30729.1
Copyright (C) Microsoft Corporation. All rights reserved.

TlbImp : error TI0000 : The input file 'dll_name.dll' is not a valid type library.
Now I'm neck deep in Dependency Walker and seeing a lot of API-MS-WIN-CORE-*, which seems to be a legacy OS thing I shouldn't be concerned with? The other files it couldn't find are DCOMP, GPSVC, and IESHIMS.DLL.

This builds clean with C++ importing the same DLL, so I'm not suspecting anything about my local configuration missing files. The C++ version is using a .h file with everything matching this pattern:
code:
__declspec(dllimport) int  __stdcall LIBNAME_FunctionName(char *Stringreply);
I'm seeing a few examples of using "PInvoke/MarshalAs" or something to import the C++ bindings. Is there a simple way to pull this DLL into c# or is my best bet building up the toy C++ example and some IPC to talk back to the C# app? That's possible, if a little ugly, but I'd really like to stick to pure C# if I can.

JawnV6
Jul 4, 2004

So hot ...

Bognar posted:

How many methods are you calling on the DLL? The way I normally go about dealing with unmanaged code and things like this is to just use P/Invoke, which could be useful if you're not using that many methods. Here's a sample from my Cairo wrapper:
<snip>

Less than 20. All string based, there's a bunch of magic numbers that get shuffled around as ASCII strings. I'll give this a shot, thanks!

JawnV6
Jul 4, 2004

So hot ...

Bognar posted:

https://msdn.microsoft.com/en-us/magazine/cc164123.aspx

This is a pretty good reference for P/Invoke. You may be interested in the sections titled "Marshaling Text" and "CharSet".

Thanks, this has made me marginally more dangerous. I got over the StackImbalance errors and I'm seeing the same results for integer return type as the C++ program. Now I'm trying to get strings back out of this board and I'm having AccessViolations, time to read this Marshaling Text section in depth!

Cheers!

e: whatever a StringBuilder is it's working

JawnV6 fucked around with this message at 02:21 on Feb 25, 2015

JawnV6
Jul 4, 2004

So hot ...
Try adding some nonce to the directory name (temp_1, temp_2, etc.)? At the very least would help isolate if it's because of the proximity of the delete/create and someone holding onto it.

JawnV6
Jul 4, 2004

So hot ...

ljw1004 posted:

That still sounds like AV.

But it wouldn't be holding the same thing? I'm worried that I'm speaking to a leaky abstraction, but Grumpy's saying that this sequence:
code:
Create("temp1");
Delete("temp1");
Create("temp2");
threw an exception trying to create temp2?

JawnV6
Jul 4, 2004

So hot ...

GrumpyDoctor posted:

That's not even the sequence; it's just
code:
Delete("temp")
Create("temp")
and the exception is thrown by the Create().
Oh, my suggestion was to add the 1 & 2 after, I understood your post that ljw quoted to be implementing that.. Just to decouple the delete/create, even with only "tempa" and "tempb" you could toggle which temp dir is in use by the current iteration and give that much more time to whatever FS goofiness is happening.

JawnV6
Jul 4, 2004

So hot ...

fleshweasel posted:

Get just the capture group. Groups have automatic number identifiers or can be named. Google knows. Also, write \d{4} not \d\d\d\d.
Yeah sounds like you're grabbing the entire match instead of the specific capture group. You can always breakpoint it and drill into the variables to see where it's putting the information you want.

JawnV6
Jul 4, 2004

So hot ...
I'm having an issue with timers. One is blocking another and I'm not sure if it's how I've set them up or if it's the terrible computer it's running on.

Timer1 is polling a serial port for data every 200ms. Timer 2 is launching a print with printDocument.Print() every 30s. According to the timestamps, when the print kicks off the first timer doesn't log the next sample until 2~3s have passed.

On a modern i7, this was working fine. I could see the print dialog blip up and disappear quickly. On this ancient Core2Duo the window pops up and is visible for a moment. I tried to decouple the timers by putting the .Print() call into a delegate kicked off with Invoke(), but the problem persisted.

Is there some multi-threading magic I'm missing or is this PC simply not up to the task of reading a serial port while printing a document?

JawnV6
Jul 4, 2004

So hot ...
I am running in a GUI. It's charting the data it gets from the serial port, nice to look at but not totally necessary. The timers are System.Windows.Form.Timer , so with what's on that SO thread it makes sense they're executing in the UI thread.

I'll try to break that out into a task.

JawnV6
Jul 4, 2004

So hot ...

EssOEss posted:

Use System.Threading.Timer for your data-reading code to make it independent of the GUI. A few seconds of UI freeze for printing is totally normal on old PCs.

Thanks, this sounds like how I should've built it in the first place. It's not as simple as I was hoping as the existing timer tick just grabbed things willy nilly.

Am I correct in thinking that in the setup I should pass in everything I'll need in the callback through the state object? For instance it's writing things out to a file through a StreamWriter, my state has to carry at least that StreamWriter through? Or is it better to declare the logResults function as static?

edit: Got it working, not proud of how. Thanks for the help! throwing static volatile on the elements from the UI thread and its recording stable samples with minimal changes to the code

JawnV6 fucked around with this message at 00:23 on Sep 5, 2015

JawnV6
Jul 4, 2004

So hot ...

crashdome posted:

I realized just how fragile the concept of time is and my brain almost melted.
I built a system that had to maintain a RTC over 10 years on a processor with 512b of RAM connected to the server over GSM, which has unreliable timestamps. At one point I had a network timestamp, device timestamp, and GSM timestamp. None were within a minute of each other.

On the stupid DAQ I've built up now, I'm using this snippet to get millis-since-epoch:
string timestamp = (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds.ToString();

In one sense sub-15ms precision doesn't matter, the sensor has it's own rate and I can detect what sample frame it's returning. I'm logging another thing, but it's on the same PC and events are several seconds long. But the discussion upthread gives me some doubt about the sensitivity to a context switch, is it having to switch over to get the time or can I assume that snippet called in a 200ms timer is relatively accurate?

JawnV6
Jul 4, 2004

So hot ...

GrumpyDoctor posted:

For an actual location to save your state, check out isolated storage.
What's wrong with the Settings class linked in the first SO answer? I've used that before, seemed nice and friendly.

RICHUNCLEPENNYBAGS posted:

My favorite Excel CSV thing
Mine is flattening out long float values (millis-since-epoch) and losing the last 8 digits of precision, despite never saving or attempting to save the file.

JawnV6
Jul 4, 2004

So hot ...

The Wizard of Poz posted:

Am I understanding correctly that 5:30 is when DST takes effect? If so in effect there is no such thing as 5:30 for that date in your timezone, it's actually 6:30. The two date/times you've provided are identical.
No. A person in Arizona, which does not use DST, has two distinct times. My time zone calls two of them the same, but the Arizonan should be able to create both times and let them remain distinct, even if they're ssh'd into a Californian server.

Adbot
ADBOT LOVES YOU

JawnV6
Jul 4, 2004

So hot ...

The Wizard of Poz posted:

You haven't lost any information, because they are literally the exact same point in time

No. They are an hour apart. One happens, then an hour goes by, and the second happens. They share a label, that doesn't magically collapse the space/time continuum between those events.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply