Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Compile Time Unmanaged DLL Checking

Compile Time Unmanaged DLL Checking

Scheduled Pinned Locked Moved C#
csharpvisual-studiohelpquestionworkspace
6 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    MKlucher
    wrote on last edited by
    #1

    Does anyone know if it's possible to have VS .NET 2003 check the DLLImport functions at compile time? FOr instance class PlatformInvokeTest { [DllImport("C_DLL.dll")] public static extern void BridgeFn(lo); public static void Main() { try { string lo = string.Empty; BridgeFn(lo); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } } While in my DLL There is no BridgeFn function that takes a string. This generates an error only on execution. While not horrible on a small scale, on a larger scale things can get pretty hairy pretty quick. If there is no way to check this at compile time any workflow suggestions to make this easier? Thanks!

    H 1 Reply Last reply
    0
    • M MKlucher

      Does anyone know if it's possible to have VS .NET 2003 check the DLLImport functions at compile time? FOr instance class PlatformInvokeTest { [DllImport("C_DLL.dll")] public static extern void BridgeFn(lo); public static void Main() { try { string lo = string.Empty; BridgeFn(lo); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } } While in my DLL There is no BridgeFn function that takes a string. This generates an error only on execution. While not horrible on a small scale, on a larger scale things can get pretty hairy pretty quick. If there is no way to check this at compile time any workflow suggestions to make this easier? Thanks!

      H Offline
      H Offline
      Heath Stewart
      wrote on last edited by
      #2

      No, the compiler does not check these things (as you've found). Just make sure that the functions are exported from the DLL you're referencing. As far as work flow, I really don't see why anyone would just "blindly" P/Invoke a function if they didn't know it was exported. Seems like a backward way of thinking. Typically, you P/Invoke a function because it's there, not vice versa. If you want to see what exports are available, I recommend using depends.exe (the Dependency Walker) from the Platform SDK (installed by default with VS.NET).

      Microsoft MVP, Visual C# My Articles

      M 1 Reply Last reply
      0
      • H Heath Stewart

        No, the compiler does not check these things (as you've found). Just make sure that the functions are exported from the DLL you're referencing. As far as work flow, I really don't see why anyone would just "blindly" P/Invoke a function if they didn't know it was exported. Seems like a backward way of thinking. Typically, you P/Invoke a function because it's there, not vice versa. If you want to see what exports are available, I recommend using depends.exe (the Dependency Walker) from the Platform SDK (installed by default with VS.NET).

        Microsoft MVP, Visual C# My Articles

        M Offline
        M Offline
        MKlucher
        wrote on last edited by
        #3

        Heath Stewart wrote: As far as work flow, I really don't see why anyone would just "blindly" P/Invoke a function if they didn't know it was exported. Seems like a backward way of thinking. Typically, you P/Invoke a function because it's there, not vice versa. Agreed, I don't know about you, but I have never written a program perfectly with out any mistakes before :-D I just wanted to avoid the case five months from now where I am trying to track down a bug and it turns out I was just passing the wrong data type in (Cause it seems like it doesn't do data type checking either) so guess that was my concern. We basiclly have DLLs that we want to tie into because C# has such and easy way to design interfaces and that stuff. We have a lot of DLL's so it will be done on a fairly large scale.

        H 1 Reply Last reply
        0
        • M MKlucher

          Heath Stewart wrote: As far as work flow, I really don't see why anyone would just "blindly" P/Invoke a function if they didn't know it was exported. Seems like a backward way of thinking. Typically, you P/Invoke a function because it's there, not vice versa. Agreed, I don't know about you, but I have never written a program perfectly with out any mistakes before :-D I just wanted to avoid the case five months from now where I am trying to track down a bug and it turns out I was just passing the wrong data type in (Cause it seems like it doesn't do data type checking either) so guess that was my concern. We basiclly have DLLs that we want to tie into because C# has such and easy way to design interfaces and that stuff. We have a lot of DLL's so it will be done on a fairly large scale.

          H Offline
          H Offline
          Heath Stewart
          wrote on last edited by
          #4

          But again, why would you P/Invoke a method before seeing if it either exists? That's like putting the cart before the horse. :) Data-type checking isn't supported because you're marshaling to an unmanaged platform. C/C++ doesn't perform any type checking, either, except for what the compiler can perform at compile-time. In an unmanaged world, arguments and return values are only pointers on the stack (most usually). There would be no way to determine this using a managed compiler. The best way to avoid errors is to truly understand the unmanaged and managed types, like that an unmanaged int is platform-dependent, i.e. 32 bits on a 32-bit processor and 64 bits on a 64-bit processor,thus you should use an IntPtr. A LONG is always 32 bits, hence is a managed Int32 (C#'s int primitive). A char* is a managed string (no ref or out) and should use CharSet.Ansi, where an LPTSTR is also a string but should use CharSet.Auto, etc. etc. One thing to note is that currently in the .NET FCL Microsoft uses int where it should be an IntPtr because .NET 1.x does not support the 64-bit platform (it will in 2.0). I suspect they will either change to using IntPtr internally or maintain two different builds specifying an int for 32-bit platforms and a long for 64-bit platforms. I honestly don't know, but making your code use an IntPtr now will ensure that when it is compiled for the 2.0 framework and run on a 32- or 64-bit platform that it will work correctly.

          Microsoft MVP, Visual C# My Articles

          M 1 Reply Last reply
          0
          • H Heath Stewart

            But again, why would you P/Invoke a method before seeing if it either exists? That's like putting the cart before the horse. :) Data-type checking isn't supported because you're marshaling to an unmanaged platform. C/C++ doesn't perform any type checking, either, except for what the compiler can perform at compile-time. In an unmanaged world, arguments and return values are only pointers on the stack (most usually). There would be no way to determine this using a managed compiler. The best way to avoid errors is to truly understand the unmanaged and managed types, like that an unmanaged int is platform-dependent, i.e. 32 bits on a 32-bit processor and 64 bits on a 64-bit processor,thus you should use an IntPtr. A LONG is always 32 bits, hence is a managed Int32 (C#'s int primitive). A char* is a managed string (no ref or out) and should use CharSet.Ansi, where an LPTSTR is also a string but should use CharSet.Auto, etc. etc. One thing to note is that currently in the .NET FCL Microsoft uses int where it should be an IntPtr because .NET 1.x does not support the 64-bit platform (it will in 2.0). I suspect they will either change to using IntPtr internally or maintain two different builds specifying an int for 32-bit platforms and a long for 64-bit platforms. I honestly don't know, but making your code use an IntPtr now will ensure that when it is compiled for the 2.0 framework and run on a 32- or 64-bit platform that it will work correctly.

            Microsoft MVP, Visual C# My Articles

            M Offline
            M Offline
            MKlucher
            wrote on last edited by
            #5

            Heath Stewart wrote: But again, why would you P/Invoke a method before seeing if it either exists? That's like putting the cart before the horse. So is there a way to do this in code? I am not the programmer writing the DLL's so while I'll try to keep my eye out the chances that something with the function (Data types etc) might change without me knowing right away.

            H 1 Reply Last reply
            0
            • M MKlucher

              Heath Stewart wrote: But again, why would you P/Invoke a method before seeing if it either exists? That's like putting the cart before the horse. So is there a way to do this in code? I am not the programmer writing the DLL's so while I'll try to keep my eye out the chances that something with the function (Data types etc) might change without me knowing right away.

              H Offline
              H Offline
              Heath Stewart
              wrote on last edited by
              #6

              This is what internal processes are for. Some version control systems alert you of changes, such as the upcoming Microsoft Team System. If something changes, the compiler won't know - it's P/Invoking an unmanaged API so there is no type metadata, plain and simple.

              Microsoft MVP, Visual C# My Articles

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups