我需要在C#应用程序的DLL中使用C函数库。我在用char *参数调用DLL函数时遇到麻烦:
C DLL:
extern "C" __declspec(dllexport) int CopyFunc(char *, char *);
int CopyFunc(char *dest, char *src)
{
strcpy(dest, src);
return(strlen(src));
}
Run Code Online (Sandbox Code Playgroud)
C#应用程序需要看起来像这样:
[DllImport("dork.dll")]
public static extern int CopyFunc(string dst, string src);
int GetFuncVal(string source, string dest)
{
return(CopyFunc(dest,source));
}
Run Code Online (Sandbox Code Playgroud)
我已经看到了使用string或StringBuilder或IntPtr代替DLL函数原型所需的char *的示例,但是我无法使它们中的任何一个起作用。我得到的最常见的例外是PInvoke正在取消堆栈的平衡,因为函数调用与原型不匹配。
有一个简单的解决方案吗?
我正在调试由 3rd 方编写的 C# 代码。该项目是一个旧的C++项目,由承包商用C#重写,我无法访问承包商。我创作了原始的 C++ 版本。
问题是当 C# 代码获取表示通过 UDP 连接接收的数据的结构的大小时。
结构体定义为:
[StructLayout(LayoutKind.Sequential,Pack=1)]
internal class PROXY_HDR {
public ushort pad;
public ushort label;
public char flags;
public ushort length;
public char[] ip = new char[4];
public ushort port;
}
Run Code Online (Sandbox Code Playgroud)
此结构的大小检索为:
int size = Marshal.Sizeof(typeof(PROXY_HDR));
Run Code Online (Sandbox Code Playgroud)
并且返回的值是 17 而不是预期的 13。有 4 个字节的差异,我怀疑是ip成员,但这只是因为它的表达方式与其他成员不同(使用“new”),但我没有其他依据可以决定.
我通常不会在我的 C# 代码中使用这种类型的封送处理来解析收到的数据包而不会出现问题,所以我不知道如何修改这个结构定义以使其与原始版本的大小“对齐”。
我可以用
int size = 13;
Run Code Online (Sandbox Code Playgroud)
但那是作弊,对吧?
我可以以某种方式修改此布局以使大小正确吗?
在SQL Server 2008R2中,我有两个表,CONFIG_DATA并且CNA_LIST:
CONFIG_DATA 有两个领域:
ID [varchar(20)] Address [int]
01 141516
02 132132
Run Code Online (Sandbox Code Playgroud)
CNA_LIST 有三个领域:
Address [int] IP1 [varchar(20)] IP2 [varchar(20)]
141516 1.2.3.4 (null)
132132 (null) 2.3.4.5
Run Code Online (Sandbox Code Playgroud)
这些是在IP1或IP2字段中具有一个或两个IP地址的现场设备(可以是其中之一,也可以是两者).
我想列出了CONFIG_DATA与表IP1从CNA_LIST表,如果它是NULL的IP2.
该Address字段链接两个表.
这样可以正常工作:
select a.ID, a.Address, b.IP1
from CONFIG_DATA a, CNA_LIST b where a.Address = b.Address
Run Code Online (Sandbox Code Playgroud)
但如果IP1是null我需要的IP2,以列为此列"IP":
我试过IF(b.IP1 <> '')b.IP1 ELSE b.IP2但语法检查器抱怨.
我需要一个可以匹配 UDP 负载中的两个字节的用于 wireshark 的捕获过滤器。我见过过滤器
UDP[8:4]
Run Code Online (Sandbox Code Playgroud)
作为匹配标准,但没有对语法的解释,我在任何wireshark wiki中都找不到它(大海捞针)。
我只需要捕获 UDP 5361,并且只需要将字节 8C:61 作为有效负载中的第三个和第四个字节的数据包。就像是
udp port 5361 and udp[2:2]=8C:61
Run Code Online (Sandbox Code Playgroud)
但我当然在猜测。谢谢你的帮助...
使用Visual Studio 2015和Visual C#Windows应用程序。
我需要一个计时器来清空主线程中的队列,因为某些UI组件已被修改。我编码为:
public Form1()
{
InitializeComponent();
Q = new ConcurrentQueue<amsg>();
timer = new System.Timers.Timer(100);
timer.Elapsed += timer_Elapsed;
timer.Enabled = true;
}
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
clsUdpMsg msg;
while (Q.TryDequeue(out msg)) handleRx(msg);
}
Run Code Online (Sandbox Code Playgroud)
但是Elapsed事件在工作线程中执行...?
如果在设计时在主窗体上放置一个计时器,则生成的原型会略有不同:
private void timer1_Tick(object sender, EventArgs e)
{
amsg msg;
while (Q.TryDequeue(out msg)) handleRx(msg);
}
Run Code Online (Sandbox Code Playgroud)
但这确实在主线程上下文中执行。
问题扩展到以这种方式创建计时器的任何线程。我以为在线程中创建的计时器会在同一线程上下文中执行经过的事件。我想念什么吗?
快速编辑:我看到这些是System.Timers.Timer和Windows.Forms.Timer不同的计时器。那么-如何可靠地创建将在创建计时器的线程中执行的计时器?
c# ×3
c++ ×2
.net ×1
dll ×1
if-statement ×1
marshalling ×1
select ×1
sql ×1
sql-server ×1
structlayout ×1
timer ×1
udp ×1
wireshark ×1