这些天做接口,将C++的非托管代码生成的dll,提供给C#上层程序使用,就需要使用 .
调用后提示找不到入口点
C++源码如下:
- —————————————————a.h—————————————————
- #ifdef A_EXPORTS
- #define A_API __declspec(dllexport)
- #else
- #define A_API __declspec(dllimport)
- #endif
- A_API int F(void);
- —————————————————a.cpp—————————————————
- #include "stdafx.h"
- #include "a.h"
- BOOL APIENTRY DllMain( HANDLE hModule,
- DWORD ul_reason_for_call,
- LPVOID lpReserved
- )
- {
- switch (ul_reason_for_call)
- {
- case DLL_PROCESS_ATTACH:
- case DLL_THREAD_ATTACH:
- case DLL_THREAD_DETACH:
- case DLL_PROCESS_DETACH:
- break;
- }
- return TRUE;
- }
- A_API int F(void)
- {
- MessageBox(NULL, "1212", "1212", MB_OK);
- return 0;
- }
C#源码函数原型声明:
[DllImport("a.dll")]
public extern static int F();
调用后提示找不到入口点
在命令行用dumpbin /exports 看函数名: ,或用exeScope查看导出的接口
dumpbin /exports a.dll
函数名不是"F"?而是"?F@@YAHXZ"
C#函数声明写成:
- [DllImport("a.dll",EntryPoint="?F@@YAHXZ")]
- public extern static int F();
这样调用成功!
原因:在C++函数声明时要将 extern "C" 添加在 DLL 函数声明之前
主要注意包含 DllImport 的代码行。此代码行根据参数值通知编译器,使之声明位于 User32.dll 中的函数并将签名中出现的所有字符串(如参数或返回值)视为 Unicode 字符串。如果缺少 EntryPoint 参数,则默认值为函数名。另外,由于 CharSet 参数指定 Unicode,因此公共语言运行库将首先查找称为 MessageBoxW(有 W 是因为 Unicode 规范)的函数。如果运行库未找到此函数,它将根据调用约定查找 MessageBox 以及相应的修饰名。受支持的调用约定只有 __cdecl 和 __stdcall。
当调用用户定义的 DLL 中所包含的函数时,,如下所示:
// The function declaration in SampleDLL.h file
extern "C" SAMPLEDLL_API int fnSampleDLL(void);
Dumpbin.exe位于 VS的安装目录\VC\bin下,如果点击dumpbin.exe提示
出现mspdb80.dll无法找到的情况,是因为VC\Bin\下没有 “msobj80.dll,mspdb80.dll,mspdbcore.dll,mspdbsrv.exe”这四个文件(在VS2005中并没有这四个文件),解决的方法:
1>直接从Common7\IDE\下复制这四个文件到VC\Bin\下即可解决
2>添加系统变量 (Path),这样:我的电脑->属性->高级->环境变量->系统变量,在path中添加C:\Program Files\Microsoft Visual Studio 8\Common7\IDE;,注意结尾最后用“;”隔开!
这样在用ml编译就不会出现mspdb80.dll文件找不到的错误了
比如数据库中的一个表有三列,有一个列是不允许为空的,其它两个列是允许为空的,我现在将这个表中的所有数据查出来后FILL到一个datatable中,现在我在查看这个datatable的各列是发现各个列的AllowDBNull都是True我现在想取得各位列在数据库中是否为空的信息,该怎么做呢?谢谢!
datatable里面默认是有约束的,表tableA,列A,B,C,D.其中A,D为不可空,A是主键唯一,表tableB,列H,J,K,L.其中H,J列不可空,若连接查询的结果包含不可空的列,A,D,H,J,而左连接查到的结果集的这里列里有空值,或A列里不唯一,就将结果集赋到Datatable里就会引发
System.Data.ConstraintException这个异常,对于这个异常不处理,程序也是不会被终止的,如果绑定Datagridview,则只会在数据单元格中显示一个红底白字的感叹号,提示列非空,或列不唯一,一般可以使用Dataset里的datatable,将dataset的EnableConstraint属性设为false,或将Datatable的Constraint约束去除。
以下是网络找到的一些资料
当使用DataSet时,经常会利用DataAdapter(也可能是CommandBuilder)与数据源进行交互。当使用DataSet时,也可以利用DataView对DataSet中的数据应用排序和筛选。也可以从DataSet继承,创建强类型DataSet,用于将表、行和列作为强类型对象属性公开。
当设计应用程序时,要考虑应用程序所需功能的等级,以确定使用DataSet或者是DataReader。
要通过应用程序执行以下操作,就要使用DataSet:
r 在结果的多个离散表之间进行导航。
r 操作来自多个数据源(例如,来自多个数据库、一个XML文件和一个电子表格的混合数据)的数据。
r 在各层之间交换数据或使用XML Web服务。与DataReader不同的是,DataSet能传递给远程客户端。
r 重用同样的记录集合,以便通过缓存获得性能改善(例如排序、搜索或筛选数据)。
r 每条记录都需要执行大量处理。对使用DataReader返回的每一行进行扩展处理会延长服务于DataReader的连接的必要时间,这影响了性能。
r 使用XML操作对数据进行操作,例如可扩展样式表语言转换(XSLT转换)或XPath查询。
对于下列情况,要在应用程序中使用DataReader:
r 不需要缓存数据。
r 要处理的结果集太大,内存中放不下。
r 一旦需要以仅向前、只读方式快速访问数据。
注填充DataSet时,DataAdapter使用DataReader。因此,使用DataAdapter取代DataSet提升的性能表现为节省了DataSet占用内存和填充DataSet需要的循环。一般来说,此性能提升只是象征性的,因此,设计决策应以所需功能为基础。
当我们使用SqlDataReader的GetSchemaTable方法是,利用下列代码打印表的结构
DataTable tb=reader.GetSchemaTable ();
foreach (DataRow dtrow in tb.Rows ){
foreach(DataColumn dtcol in tb.Columns ){
Console.Write ("\t"+ dtcol.ColumnName+"="+dtrow[dtcol] );
}
Console.Write ("\n");
}
注意,该方法返回的并不是我们操作的数据表,而是一个描述列的元数据的一个结构表,类似下面的:
列名称 列序号 列长度 列类型(...)
第一列
第二列
就是说返回的 table对象的 ROws属性 是我们操作表的所有列的集合,而COLUMNS属性是所有列特征的集合
这些列特征,称为列的元数据,有下列一些字段
对于 GetSchemaTable 方法,将按以下顺序返回关于每个列的元数据:
DataReader 列 说明
ColumnName 列的名称;它可能不唯一。如果无法确定该名称,则返回空值。此名称始终反映最近对当前视图或命令文本中的列进行的重命名。
ColumnOrdinal 列的序号。它对于行的书签列(如果有的话)为零。其他列从一开始编号。该列不能包含空值。
ColumnSize 列中值的最大可能长度。对于采用固定长度数据类型的列,它是该数据类型的大小。
NumericPrecision 如果 ProviderType 是数值数据类型,则它是列的最大精度。精度取决于列的定义。如果 ProviderType 不是数值数据类型,则它为空值。
NumericScale 如果 ProviderType 是 DBTYPE_DECIMAL 或 DBTYPE_NUMERIC,则为小数点右侧的位数。否则,它为空值。
IsUnique true:基表(BaseTableName 返回的表)中的任何两行在该列中都不能有相同的值。如果此列本身为一个键,或如果有一个仅应用于该列的 UNIQUE 类型约束,那么 IsUnique 一定为 true。false:在基表中该列可以包含重复值。该列的默认值为 false。
IsKey true:此列是行集合中合起来可唯一地标识该行的一组列中的一列。IsKey 设置为 true 的一组列必须唯一地标识行集合中的一个行。不要求此列集是最小列集。这组列可以从基表主键、唯一约束或唯一索引生成。false:唯一地标识该行时不需要此列。
BaseServerName SqlDataReader 使用的 Microsoft SQL Server 实例的名称。
BaseCatalogName 包含列的数据存储区中的目录的名称。如果不能确定基目录名称,则为 NULL。该列的默认值为空值。
BaseColumnName 数据存储区中列的名称。如果使用别名,它可能不同于在 ColumnName 列中返回的列名称。如果无法确定基列名称,或者如果行集合列从数据存储区中的列导出但不等于该列,则为空值。该列的默认值为空值。
BaseSchemaName 包含列的数据存储区中的架构的名称。如果无法确定基架构名称,则为空值。该列的默认值为空值。
BaseTableName 包含列的数据存储区中的表或视图的名称。如果无法确定基表名称,则为空值。该列的默认值为空值。
DataType 映射到列的 .Net Framework 类型。
AllowDBNull 如果使用者可以将此列设置为空值,或者如果提供者不能确定使用者是否可以将此列设置为空值,则设置该值。否则,不设置该值。即使列无法设置为空值,它仍可能包含空值。
ProviderType 列的数据类型的指示符。如果不同行的列数据类型不同,则它必须为 Object。该列不能包含空值。
IsAliased 如果列名称为别名,则为 true;否则为 false。
IsExpression 如果此列为表达式,则为 true;否则为 false。
IsIdentity 如果此列为标识列,则为 true;否则为 false。
IsAutoIncrement true:该列以固定的增量向新行赋值。false:该列不以固定的增量向新行赋值。该列的默认值为 false。
IsRowVersion 如果列包含无法写入的不变的行标识符,并且除了标识行外没有其他有意义的值,则设置该值。
IsHidden 如果列是隐藏的,则为 true;否则为 false。
IsLong 如果列包含二进制长对象 (BLOB)(它包含非常长的数据),则设置该值。非常长的数据的定义针对于提供程序。
IsReadOnly 如果不能修改该列,则为 true;否则为 false。
在C#WINDOWS创建多线程处理遇到“不是此控件创建的线程”的问题,虽然网上有人已给出解决方法,并且我也是按此方法解决,不过我感觉还是有必要记录一下,嘿嘿!
主要解决步骤是:
首先创建delegate委托与控件的赋值方法,有多少个控件需要,则创建多少个委托,例,我有两个控件需在另一个事件中被使用,则创建两个委托,代码如下:
//建立委托
delegate void setLblStr(string str);
//设置LABLE控件的TEXT值
void SetLblStr(string str)
{
this.lblDown.Text = str;
this.lblDown.Update();
}
//建立委托
delegate void setTxtStr(String str);
//设置TEXT控件的TEXT值
void SetTxtStr(String str)
{
txtUrls.Text = str;
txtUrls.Update();
}
然后在使用线程的事件中调用Invoke方法来调用委托实现,如下代码:
//创建委托实例,把要处理的方法传入委托则OK了
setLblStr sl = new setLblStr(SetLblStr);
//调用Invode()方法调用委托,并传参入委托;
this.Invoke(sl, "下载中,请稍候..........");
//创建委托实例,把要处理的方法传入委托则OK了
setTxtStr st1 = new setTxtStr(SetTxtStr);
//调用Invode()方法调用委托,并传参入委托
this.Invoke(st1, temp.ToString());//temp是定义好的stringBuilder对象
OK,问题处理完成,再哪要处理就直接调用委托处理就行了,嘿嘿!
为了安全起见,要求使用强SA密码。请使用SAPWD开关提供同一密码
部分朋友安装SQL Desk Top Engine (SQL2000桌面版)时可能出现一下信息:
"为了安全起见,要求使用强SA密码。请使用SAPWD开关提供同一密码。有关详细信息,请参阅自述文件。安装程序将立即退出。”
遇到这个问题解决方法是:
找到msde安装目录下的setup.ini,打开修改成下面这个样子
[Options]
SECURITYMODE=SQL
SAPWD=please
其中SAPWD后的"please"是你的sa的密码。(你也可以改成你自己的)。
然后双击安装即可.
MSDE 2000 是一个数据库引擎,Microsoft 和其他公司所推出的几个产品均包括了该引擎。在大多数情况下,MSDE 为不需要 SQL Server 2000 这种规模的产品的用户提供了一个替代选择。MSDE 2000 默认情况下没有被安装。以下列表中的产品均附带了早起版本的 MSDE,没有包括通过 SQL Server 2000 Service Pack 3a 提供的安全更新。默认情况下,Windows XP SP2 会限制这些产品执行本地访问,除非应用了SQL Server Service Pack 3a 服务包。可以通过以下地址下载累积服务包:Windows Update。 以下 Microsoft 产品包括了 MSDE,但是没有默认安装该产品: Access 2002 ASP.NET Web Matrix Tool MSDN Universal and Enterprise subscriptions Office XP (Developer and Professional Editions) Visual FoxPro 7.0 Visual Studio .NET (Architect, Developer, and Professional Editions) 以下产品附带了 MSDE,而且默认安装了该产品: Application Center 2000 BizTalk Server 2002 Partner Edition Microsoft Encarta Class Server 1.0 Host Integration Server 2000 Microsoft Operations Manager 2000 Project Server 2002 and 2003 Retail Management System 1.0 SharePoint Team Services Small Business Manager 6.2 and 6.3 Stress Tools version 1.2 Visio 2000 Enterprise Edition Visio Enterprise Network Tools (VENT) Windows XP Embedded Build ToolWindows XP SP2 可能会影响 Microsoft SQL Server 2000 Desktop Engine (MSDE 2000) 的工作行为。如果您通过 TCP/IP、命名管道或者远程过程调用(RPC)访问网络,Windows 防火墙会阻止数据库连接到网络。如果您正在使用安装了 SQL Server 2000 SP3a 的 MSDE 2000,则不应该遇到问题,因为该网络和 SQL Browser 技术在默认情况下已经被关闭了。 Microsoft 以外的很多公司也在程序中使用了 MSDE,所以我们鼓励所有用户检查是否安装了 MSDE 2000。 为了检查计算机上是否安装了 MSDE 2000,请按照如下步骤操作: 右击 我的电脑 图标。 选择 管理 双击 服务和应用程序 双击 服务 如果 MSSQLSERVER 存在于服务列表中,说明计算机已经安装了 MSDE 的默认实例。如果在列表中发现了 MSSQL$**** 的字样,则说明可能存在其他实例,此处的星号代表实例的名称。为了保护 MSDE 程序的安全,可以执行如下操作: 升级到 MSDE 的最新版本。 为了下载最新版本,请访问 MSDE 站点。 下载 Windows XP SP2 Release Candidate 1 并测试您的应用程序。 为了下载软件并获得更多技术信息,请访问 TechNet 站点上的 面向 IT 专业人员的 Windows XP SP2 资源 页面。
“runtiem”,一般翻译就译成“运行时”。
但具体的含义可能因环境而有所不同。
比如:
(1)virtual functions are bound at runtime.
(2)The CLR(Comman Language Runtime) will never JIT the method that 's never called.
(3)Such kind of link error is usually caused by an incompatible version of CRT(C Runtime) lib.
以上三个“运行时”的含义就不完全相同。虽然究其词源的话也算“本是同根生”了。
RunTime就是运行时的意思。
程序分为几个状态,编辑时-> 编译时-> 静态时-> 运行时
比如有些错误在编译的时候是不会出现的,就是程序在语法上没有问题。但在运行时,因为缺少资源等因素可能出现运行时错误。叫做runtime error!
我的理解 在Java和.NET里面,Runtime是一个同Compile-time相对应的概念。程序代码首先在编译时成为ByteCode或者IL,在运行时才被编译为原生代码。
咱们从字面上理解是 "运行时 "
我理解是:
在程序中,异常分为检查型异常和运行时异常.
检查型异常是程序员必须在程序中捕获的,
而运行时异常是可以先不处理,在程序运行时有虚拟机抛出(JAVA方面)
另一个概念就是对象在上塑造型时,虚拟机在编译时并不知道要引用哪一个对象,
而在程序运行时才确定要引用哪一个对象.
这是我的理解,对与不对供楼主参考,还请高手指正
有很多计算机术语用中文翻译很难理解,容易出错。
比如高级语言,原本为high level language,被翻译成“高级语言”后,很容易被理解为advanced language。以至于大家会为C到底归为高级语言还是低级语言争吵。如果从英文的角度了解高级语言和低级语言的来源,则可以更好的理解术语的原意。 所以建议翻译者建立一个关键词的附录表,说明术语的英文,方便读者理解。
运行时刻是指一个程序在运行(或者在被执行)的状态。也就是说,当你打开一个程序使它在电脑上运行的时候,那个程序就是处于运行时刻。在一些编程语言中,把某些可以重用的程序或者实例打包或者重建成为“运行库"。这些实例可以在它们运行的时候被连接或者被任何程序调用。 Runtime类封装了运行时的环境。每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接。
一般不能实例化一个Runtime对象,应用程序也不能创建自己的 Runtime 类实例,但可以通过 getRuntime 方法获取当前Runtime运行时对象的引用

