别人给了我一个连接对方数据库的dll,用vc编的,我用c#引用
public unsafe class SW_DbOperaClass
{
 [DllImport(@"d:\sw_midware_client.dll", EntryPoint = @"?nExecQuery@SW_DbOperaClass@@QAEHIPBD00AAVSW_ResultClass@@H@Z", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Winapi)]
 public static extern int nExecQuery(int OperType, StringBuilder ClientID, StringBuilder TableName, StringBuilder Statement, ref SW_ResultClass rs, int timeOut);
}我在调用时
iretval = SW_DbOperaClass.nExecQuery(c, user, table, queryword, ref rs, d);
就报上述错误。其中SW_ResultClass也是我所引用的dll中生成的类,我觉的问题出在这里public unsafe class SW_ResultClass
{
            [DllImport(@"d:\sw_midware_client.dll", EntryPoint = @"?nGetFieldCount@SW_ResultClass@@QAEHXZ", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Winapi)]
            public static extern int nGetFieldCount();
            [DllImport(@"d:\sw_midware_client.dll", EntryPoint = @"?nGetFieldNameByIndex@SW_ResultClass@@QAEPBDH@Z", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Winapi)]
            public static extern StringBuilder nGetFieldNameByIndex(int nIndex);
}请诸位看看该怎么解决?

解决方案 »

  1.   

    把你的DLL源代码中函数的声明也贴出来!对比以下就能发现!
      

  2.   

    DLL是别人的,没有源代码,只能用exeScope查看是如下
    导出, sw_midware_client.dll
    序列         地址         名字
    00000001 10026A50 ??0SW_DbOperaClass@@QAE@ABV0@@Z
    00000002 100263F2 ??0SW_DbOperaClass@@QAE@XZ
    00000003 10026C8A ??0SW_Midware_Util@@QAE@ABV0@@Z
    00000004 100275F4 ??0SW_Midware_Util@@QAE@XZ
    00000005 10026519 ??0SW_ResultClass@@QAE@ABV0@@Z
    00000006 100261A9 ??0SW_ResultClass@@QAE@XZ
    00000007 10027031 ??1SW_DbOperaClass@@QAE@XZ
    00000008 1002605A ??1SW_Midware_Util@@QAE@XZ
    00000009 10027293 ??1SW_ResultClass@@QAE@XZ
    0000000A 10027216 ??4SW_DbOperaClass@@QAEAAV0@ABV0@@Z
    0000000B 10026960 ??4SW_Midware_Util@@QAEAAV0@ABV0@@Z
    0000000C 1002696A ?CloseSocket@SW_Midware_Util@@QAEHI@Z
    0000000D 10026B5E ?ConnServ@SW_Midware_Util@@QAEIPADH@Z
    0000000E 1002728E ?Init@SW_Midware_Util@@QAEHV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z
    0000000F 1002612C ?Next@SW_ResultClass@@QAEHXZ
    00000010 10027158 ?RecvData@SW_Midware_Util@@QAEHIPADHH@Z
    00000011 100273E7 ?SendData@SW_Midware_Util@@QAEHIPADHH@Z
    00000012 10026A46 ?Write_Op_Log@SW_Midware_Util@@QAAXHPBDZZ
    00000013 100264BF ?assembleSerial@SW_Midware_Util@@QAE_KHHPAD@Z
    00000014 1002613B ?attrClear@SW_ResultClass@@AAEXAAUResultAttr@@@Z
    00000015 1002709F ?bIsEOF@SW_ResultClass@@QAE_NXZ
    00000016 1002600F ?char2ResultAttrs@SW_ResultClass@@AAEHPADH@Z
    00000017 1002740F ?char2Results@SW_ResultClass@@AAEHPADHHAAUResult_cluster@@@Z
    00000018 10027568 ?checkAndRecvErrMesg@SW_Midware_Util@@QAEHIIIH@Z
    00000019 1002667C ?disassembleSerial@SW_Midware_Util@@QAE_N_KAAH1PAD@Z
    0000001A 100268F2 ?getAutoCommit@SW_DbOperaClass@@QAE_NXZ
    0000001B 10026F82 ?getDatetime@SW_Midware_Util@@QAEXAAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z
    0000001C 100273BA ?getElapsedTime@SW_Midware_Util@@QAEMXZ
    0000001D 100264AB ?getErrorCode@SW_DbOperaClass@@QAEHXZ
    0000001E 1002769E ?getErrorCode@SW_Midware_Util@@QAEHXZ
    0000001F 10027225 ?getErrorCode@SW_ResultClass@@QAEHXZ
    00000020 100274AA ?getErrorMessage@SW_DbOperaClass@@QAEPADH@Z
    00000021 10026D93 ?getErrorMessage@SW_Midware_Util@@QAEPADH@Z
    00000022 10026532 ?getErrorMessage@SW_ResultClass@@QAEPADH@Z
    00000023 10026C85 ?getResultsFromServer@SW_ResultClass@@AAEHHAAUResult_cluster@@@Z
    00000024 10027676 ?getVersion@SW_DbOperaClass@@QAEPADXZ
    00000025 10026EEC ?getVersion@SW_Midware_Util@@QAEPADXZ
    00000026 10027518 ?nClose@SW_DbOperaClass@@QAEHXZ
    00000027 10027365 ?nCommit@SW_DbOperaClass@@QAEHH@Z
    00000028 10026AF5 ?nConnQueryServer@SW_DbOperaClass@@AAEHXZ
    00000029 10027522 ?nExecLoad@SW_DbOperaClass@@QAEHPAD0PAXK_N@Z
    0000002A 10027248 ?nExecQuery@SW_DbOperaClass@@QAEHIPBD00AAVSW_ResultClass@@H@Z
    0000002B 10026B90 ?nExecUpdate@SW_DbOperaClass@@QAEHPBD0H@Z
    0000002C 10026424 ?nGetCurResultCount@SW_ResultClass@@QAEJXZ
    0000002D 100276B7 ?nGetFieldCount@SW_ResultClass@@QAEHXZ
    0000002E 10026A6E ?nGetFieldNameByIndex@SW_ResultClass@@QAEPBDH@Z
    0000002F 1002652D ?nGetFieldTypeByIndex@SW_ResultClass@@QAEHH@Z
    00000030 100269BF ?nGetFieldValueByFieldName@SW_ResultClass@@QAEPBDPBD@Z
    00000031 1002620D ?nGetFieldValueByIndex@SW_ResultClass@@QAEPBDH@Z
    00000032 10026096 ?nGetLoadtabInfo@SW_DbOperaClass@@AAEHXZ
    00000033 100264A6 ?nGetResultAttrs@SW_ResultClass@@QAEHXZ
    00000034 100261F4 ?nGetResultPercent@SW_ResultClass@@QAEHXZ
    00000035 10027360 ?nGetResultTotal@SW_ResultClass@@QAEJXZ
    00000036 100276B2 ?nReset@SW_Midware_Util@@QAEHXZ
    00000037 100263FC ?nReset@SW_ResultClass@@QAEHXZ
    00000038 10026C58 ?nRollBack@SW_DbOperaClass@@QAEHH@Z
    00000039 1002731A ?recCopy@SW_ResultClass@@AAEHAAUResult_sig@@UResult_cluster@@H@Z
    0000003A 1002729D ?recsClear@SW_ResultClass@@AAEXAAUResult_cluster@@@Z
    0000003B 100262EE ?recsClear@SW_ResultClass@@AAEXAAUResult_sig@@@Z
    0000003C 10026F9B ?recsCopy@SW_ResultClass@@AAEHAAUResult_cluster@@0HHH_N@Z
    0000003D 1002651E ?recsRenew@SW_ResultClass@@AAEHHAAUResult_cluster@@@Z
    0000003E 100263A7 ?setAutoCommit@SW_DbOperaClass@@QAEH_N@Z
    0000003F 10026195 ?setErrorCode@SW_Midware_Util@@QAEXH@Z
    00000040 1002685C ?setStartTime@SW_Midware_Util@@QAEXXZ
    00000041 100262BC ?waitResponseOfQuery@SW_DbOperaClass@@AAEHXZ
      

  3.   

    如果调用DLL尽量不要在繁杂的线程中。。
    我原来的摄像头DLL也这样后来变成主线程就好了。
      

  4.   

    给的.h文件是:
    #ifdef STATICLIB ///////// 静态库 ///////////
    #define SZ5_MIDWARE_API
    #else ///////// 动态库 ///////////
    #ifdef SZ5_MIDWARE_EXPORTS
    #define SZ5_MIDWARE_API __declspec(dllexport)
    #else
    #define SZ5_MIDWARE_API __declspec(dllimport)
    #endif // SZ5_MIDWARE_EXPORTS
    #endif // STATICLIB
    #else //////////// For Linux
    #define SZ5_MIDWARE_API
    #endif
    /*操作类型定义*/
    #define DB_QUERY 1 // 数据库查询
    #define DB_QUERY_LOAD 2 // 数据库查询并加载
    #define ALL_LOG 0 // 详细日志模式
    #define IMPORTANT_LOG 1 // 精简日志模式
    #define NONE_LOG 2 // 无日志模式
    using namespace std;
    // 定义64位整型
    typedef unsigned long long LARGE_INT;
    using namespace std;
    struct Attr_sig
    {
    string  name;
    int type;
    int length;
    };struct ResultAttr
    {
    int attr_num;
    Attr_sig *attributes;
    };struct Result_sig
    {
    int *offset;
    char *result_buf;
    };struct Result_cluster
    {
    int current_place; // 指向本结构中未读记录起始位置
    int result_cnt_max; // 本结构中可存储的最大结果数.
    int result_num; // 本结构中存储的结果集数.
    Result_sig *results;
    };
    // 加载相关
    // 加载节点的IP结构,包括Ip和port
    struct LOAD_IP  
    {       
    char    load_ip[24];
    char    port[8];
    };
    struct  TAB_IPS
    {       
    char            tabname[32];
    vector<LOAD_IP> load_ips;
    int             ip_sum;
    int             current_ip;
    };/*公共应用类定义该类定义与应用程序无关*/
    class SZ5_MIDWARE_API SW_Midware_Util
    {
    private:
    #ifdef WIN32
    time_t tm_begin, tm_end;
    #else
    struct timeval tm_begin;
    struct timeval tm_end;
    #endif int midware_errno; // 错误号
        public: SW_Midware_Util();
    ~SW_Midware_Util(); string content;
    /*
    * 配置信息
    */
    int loglevel; // 记帐日志级别
    string log_filename;
    int logfile_maxsize;
    int log_fp; string errmesg;
    string ora_errmesg;
    int exceplang; // exception错误信息语种 LARGE_INT connserial; int timeout_global;
    int timeOutDef; // 缺省timeOut值 string queryserviceip; // 查询应用服务器ip地址
    int queryserviceport; // 查询应用服务器socket端口号设置。
    SOCKET queryserviceid; string loadconfservip;          // 加载配置应用服务器ip地址
    int loadconfservport;           // 加载配置应用服务器socket端口号设置。 bool statictime; int max_result_store_inmem; // 缺省返回最大结果集设置
    int flushconftimes;             // 连接加载配置服务器更新配置信息间隔调用nExecLoad次数 SW_Midware_Util& operator = (const SW_Midware_Util&); char *getVersion(void); // 获得当前版本号 /*
    *  通信相关
    */
    SOCKET ConnServ(char *servername, int port); // 客户端连接服务器端
    int SendData(SOCKET listen_fd, char *data, int length, int timeout); // 发送消息
    int RecvData(SOCKET listen_fd, char * recvbuf, int size, int timeout); // 消息接收
    int CloseSocket(SOCKET listen_fd); // 关闭socket连接 /*
    * 应用类方法
    */
    void setStartTime();
    float getElapsedTime(); void getDatetime(string &);
    void Write_Op_Log(int log_type, const char*, ...); // 日志文件写
    void setErrorCode(int errno_arg);
    int getErrorCode();
    char * getErrorMessage(int errno_arg); /*
    * 分解连接串号ConnSerial
    */
    bool disassembleSerial(LARGE_INT connserial_arg, int & processid, int & serialno, char* clientip); /*
    * 重组连接串号ConnSerial
    */
    LARGE_INT assembleSerial(int processid, int serialno, char* clientip); int nReset(); int Init(string conf_filename); int checkAndRecvErrMesg(SOCKET serviceid, unsigned int mesgtype, unsigned int size, int timeout);};/*
    * Notice: 以下两个类由用户应用程序调用。
    * By J.Zhang on 2007-12-17
    */
    class SZ5_MIDWARE_API SW_ResultClass
    {
        private:
    long result_total;
    long result_valid;
    long cursor;
    bool IsEof;
    int getrectimes; Result_cluster record_cluster;
    Result_sig single_record;
    ResultAttr resultattr; // 结果集属性 SW_ResultClass & operator= ( const SW_ResultClass& rec); int char2ResultAttrs(char *, int);
    int char2Results(char *, int, int, Result_cluster &);
    int getResultsFromServer(int, Result_cluster &); void recsClear(Result_cluster & rec_cluster); // 对应于rec_cluster的清除方法
    void recsClear(Result_sig & rec_single); // 对应于rec_single的清除方法
    void attrClear(ResultAttr & resultattr);
    int  recsRenew(int, Result_cluster & rec_cluster);
    int  recsCopy(Result_cluster & dest, Result_cluster & src, int dest_start, int src_start, int count, bool movepoint);
    int  recCopy(Result_sig & dest, Result_cluster src, int pos);    public:
    SW_Midware_Util sw_midware_util; bool IsBad;
    bool HasExec;
    bool connected; SW_ResultClass( );
    ~ SW_ResultClass( ); int nReset(); /*
    * 等待中间件服务操作应答并获得结果集属性
    */
    int nGetResultAttrs(); /*
    * 获得当前任务状态;
    * status状态描述:
    * 0——操作完成;
    * 1——操作未完;
    * 2——查询故障;
    */
    int nExecStatus(const char *ClientID, int & status); /*
    * 得到当前可用的结果集记录条数。
    * 返回值大于等于0时表示可用记录条数,<0表示错误
    * 该请求指针对查询语句。
    */
    long nGetCurResultCount(); /*
    * 得到本次查询结果集总大小
    * 返回值大于等于0时表示结果集记录条数,<0表示错误
    * 该请求指针对查询语句。
    * 本接口为阻塞调用接口,阻塞至本次查询完成。
    */
    long nGetResultTotal(); /*
    * 得到本次查询进度
    * 返回为0-100间的某个数,100表示完成,-1表示错误
    * 该请求指针对查询语句。
    * 本接口为进度估计值,并非精确值
    */
    int nGetResultPercent(); /*
    * 结果记录是否取完,即游标是否到末尾,如果已取完,返回true
    * 该请求指针对查询语句。
    */
    bool bIsEOF(); /*
    * 取结果关系的属性个数
    * 返回值:语句执行情况,0表示成功,<0表示错误
    * 该请求指针对查询语句。
    */
    int nGetFieldCount();  /*
    * 取属性名,属性下标从0开始
    * 返回值:语句执行情况,非空表示成功,NULL表示错误
    * 该请求指针对查询语句。
    */
    const char * nGetFieldNameByIndex(int nIndex); /*
    * 取属性类型,属性下标从0开始
    * 返回值:语句执行情况,0表示成功,<0表示错误
    * 该请求指针对查询语句。
    * 支持的类型如下:
    *   #define SQL_VARCHAR2 1
    *   #define SQL _CHAR 96
    *   #define SQL _DATE 12
    *  #define SQL _ROWID 104
    *   #define SQL _NUMBER 2
    *   #define SQL _LONG 8
    *   #define SQL _RAW 23
    *   #define SQL _LONGRAW 24
    *  #define SQL _UNKNOWN 0
    */
    int nGetFieldTypeByIndex(int nIndex); /*
    * 取当前结果记录的第nIndex个属性值,属性下标从0开始
    * 返回值:语句执行情况,0表示成功,>0表示警告,<0表示错误
    */
    const char * nGetFieldValueByIndex(int nIndex); /*
    * 根据字段名获取字段值
    */
    const char * nGetFieldValueByFieldName(const char* FieldName); /*
    * 向下移动结果集游标;
    * 每调用一次获得一条新的结果集记录。
    * 当全部结果集取完,返回false;
    */
    int Next(); /*
    * 获取错误号
    */
    int getErrorCode(); /* 错误信息获得:
    * 1、参数描述:
    * 错误号errno
    * 返回错误信息描述字符串;
    */
    char * getErrorMessage(int errno_arg);
    };class SZ5_MIDWARE_API SW_DbOperaClass
    {
        private:
    int nConnQueryServer();
    string clientip;
    bool connected;
    bool autocommit; /*
    * 等待中间件服务操作应答
    */
    int waitResponseOfQuery();
    bool istransaction; //与加载相关的变量
    vector<TAB_IPS>         tab_ips;
    int                     tab_sum; int nGetLoadtabInfo(); // 获得加载配置信息服务器配置信息    public:
    SW_Midware_Util sw_midware_util; SW_DbOperaClass( );
    ~ SW_DbOperaClass(); char *getVersion(void); // 获得当前版本号
    int nExecQuery(unsigned int OperType, const char *ClientID, const char *TableName, const char *Statement, SW_ResultClass & rs_arg, int timeOut); /* 例如INSERT, UPDATE, DELETE的SQL指令,如CREATE/ALTER等的 
    * DDL指令,或者存储过程可通过该接口执行。
    * 返回INSERT, UPDATE or DELETE所涉及的记录数或返回0表示未涉及
    * 任何记录。
    *
    * 事务操作,以调用setAutoCommit(false)方法为事务起始,
    * 以调用nRollback/nCommit或非事务操作为结束,如未
    * 显式调用则缺省调用nCommit;
    */

    int nExecUpdate(const char *ClientID, const char *Statement, int timeOut); /*
    * 设置是否自动提交。
    * AutoCommit值:
    * true —— 数据库自动commit;
    * false —— 用户手工commit;
    */
    int setAutoCommit(bool AutoCommit); /*
    * 获取自动提交状态。
    */
    bool getAutoCommit();
    int nCommit(int timeOut);
    int nRollBack(int timeOut);
    int nExecLoad(char *ClientID, char* TableName, void* DataBuf, unsigned long DataBufLen, bool RestorBadRecFile); /*
    * 查询完成关闭本次操作,调用后相应结果集类不可用;
    * 事务操作缺省执行Commit操作;
    */
    int nClose(); /*
    * 获取错误号
    */
    int getErrorCode(); /* 错误信息获得:
    * 1、参数描述:
    * 错误号errno
    * 返回错误信息描述字符串;
    */
    char * getErrorMessage(int errno_arg);
    };
    #endif
      

  5.   

    曾遇到过这样的问题,dll的出参是个字符串,直接定义string outStr = ""后调用就报错,后来怀疑是字符串内存分配的问题,改成StringBuilder outStr也不行,但是定义成string outString = "                                   ";就可以,一直很纳闷
      

  6.   

    还不如把DLL打包上来,让大家下载测试,呵呵
      

  7.   

    可能是DllImport DLL C部分参数在C#里不能直接使用,用Marshall 格式化下参数